联网 五子棋 PHP + MySQL

目录结构:
根目录下:/
gobang.html
gobang.js
jquery-3.6.0.min.js
gobag文件夹下: /gobang/
gobanglog.php
gobangstate.php

gobang.html

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>五子棋对战</title>
        <style type="text/css">
            * {margin: 0px;padding: 0px;}
            .wbar .title {text-align: center;background-color: burlywood;height: 30px;}
            .wbar button.initlogin {position: fixed; right: 0px; top: 0px;padding: 1%;}
            .info {width: 100%;background-color: bisque;height: 25px;}
            .login {
                text-align: center;
                padding: 2%;
                position: fixed; top: 50%; 
                left: 50%; transform: translate(-50%, -50%);
                border: 2px #333 solid;
                background-color: #fff;
            }
            .login input {
                margin: 2%;
                text-align: center;
            }
            .light {
                animation: animate 5s linear infinite;
            }
            @keyframes animate{
                0%,50%,100%
                {
                    background-color: #000;
                    color: #fff;
                }
                25%, 75%
                {
                    background-color: #fff;
                    color: #000;
                }
            }
            div.main div.dialog {
                font-size: 12px;
                display: block;
                height: 200px;
                width: 240px;
                z-index: 10;
                position: fixed;
                left: 50%;
                top: 50%;
                opacity: 1;
                background-color: white;
                transform: translate(-50%, -50%);
                border: 1px #999 solid;
                padding: 10px;
                box-shadow: 0px 1px 5px #aaa;
            }
            /* 拖动时半透明 */
            div.main div.dialog.selected {
                opacity: 0.5;
            }
            /* 鼠标在 .bar 区域时显示“移动”形状 */
            div.main .dialog .bar {  cursor: move; }
            /* .bar .title 的字体 */
            div.main .dialog .bar .title { font: bold 14px/20px "Microsoft Yahei";  }
            /* 浮动到右侧;鼠标在 × 上时显示手指形状;超链接不显示下划线 */
            div.main .dialog .bar .close{ float: right; cursor: pointer; text-decoration: none; font-family: Arial !important; font-weight: bold; font-size: 24px !important;color: #999;}
            /* 鼠标在 × 上时字体颜色改变(加深) */
            div.main .dialog .bar a.close:hover { color: #000;}
            /* .content “装”不下全部内容时超出范围也要显示,设置字体和行间距 */
            div.main .dialog .content {
                overflow:visible;
                font-size: 14px;
                line-height: 180%;
            }
            /* 超链接的显示设置 */
            div.main .dialog .content a {color: #333;text-decoration: none;}
            div.main .dialog .content a:hover {color: #000; text-decoration: underline;cursor: pointer;}
        </style>
        <script type="text/javascript" src="jquery-3.6.0.min.js"></script>
        </head>
    <body onload="load()" onbeforeunload="before_exit_page()">
        <div class="wbar">
            <h2 class="title">五子棋对战</h2>
            <button type="button" onclick="show_login()" class="initlogin">登录</button>
        </div>
        <div class="info">
            <span class="player1" onclick="show_player1_info()">player1</span>
            <span class="playtime" style="position: absolute; left: 50%;transform: translateX(-50%);">00:00</span>
            <span class="player2" onclick="show_player2_info()" style="float: right;">player2</span>
        </div>
        <div class="login" style="display: none;">
            <form action="/gobanglogin">
                <p style="margin-bottom: 5%;">登录</p>
                <label for="uname">用户名</label><br>
                <input type="text" name="uname" id="uname"><br>
                <label for="pword">密码</label><br>
                <input type="password" name="pword" id="pword" autocomplete="off"><br>
                <input type="button" value="取消" onclick="cancel_login()">
                <input type="button" value="登录" onclick="login()"><br>
            </form>
        </div>
        <div class="main">
            <canvas id="canvas">your browser isn't support canvas!</canvas>
            <div class="dialog" style="display: none;">
                <div class="bar">
                    <span class="title">信息</span>
                    <a class="close" href="javascript:close_dialog()">×</a>
                </div>
                <div class="content">
                    <br><br>
                    <strong id="dialog_info">123</strong>
                    <br><br>
                </div>
            </div>
        </div>
        <div class="ctrl">
            <button type="button" onclick="get_user_list()">获取在线用户列表</button>
            <button type="button" onclick="new_game()">新游戏</button>
            <!--button type="button" οnclick="get_back()">悔棋</button>
            <button type="button" οnclick="get_fail()">认输</button>
            <button type="button" οnclick="get_tie()">请求和棋</button-->
            <button type="button" onclick="logout()">登出</button>
        </div>
        <div class="user-list" style="display: none;">
            <table style="width: 100%;text-align: center;">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>比赛中</th>
                        <th>匹配中</th>
                        <th>对战id</th>
                        <th>胜局</th>
                        <th>输局</th>
                        <th>平局</th>
                    </tr>
                </thead>
                <tbody class="users"></tbody>
            </table>
        </div>
        <script type="text/javascript" src="gobang.js"></script>
    </body>
</html>

展示

goabng.js

// 自定义元素选择函数
function $$(sel){
    if(sel.substr(0,1) != "#"){
        return document.querySelector(sel);
    } else {
        return document.querySelectorAll(sel);
    }
}
// 显示登录窗口
function show_login(){$$("div.login").style.display = "block";}
// 隐藏登录窗口
function cancel_login(){$$("div.login").style.display = "none";}
// 显示玩家1的信息
function show_player1_info(){
    $$("strong#dialog_info").innerHTML = "玩家1:"+player1.uname+"<br>胜局:"+player1.winnum+"<br>输局:"+player1.lostnum+"<br>平局:"+player1.tienum;
    show_dialog();
}
// 显示玩家2的信息
function show_player2_info(){
    $$("strong#dialog_info").innerHTML = "玩家2:"+player2.uname+"<br>胜局:"+player2.winnum+"<br>输局:"+player2.lostnum+"<br>平局:"+player2.tienum;
    show_dialog();
}
// 定时连接服务器,获取信息
function get_info(){
    get_user_list();
    var poststr = "uname="+username+"&pword="+password+"&q=0";
    // 获取自己信息
    for(var i=0;i<players.length;i++){
        if(players[i].uname == player1.uname){
            my = players[i];
            break;
        }
    }
    // 如果当前在等待
    console.log("正在等待...");
    if(state == "wait"){
        // 如果匹配到了
        if(my.iscomp == 1){
            console.log("匹配到了...");
            // 更新对战对象信息
            for(var i=0;i<players.length;i++){
                if(players[i].id == my.beatid){
                    player2 = players[i];
                    break;
                }
            }
            $$("span.player2").innerHTML = player2.uname;
            state = "comp"; // 设置状态为对战中
            // 开始计时
            int_get_time = setInterval(get_time, 1000);
            // 如果对方已落子
            if(player2.droped == 1){
                console.log("对方落子...");
                fl = {
                    x:player2.dropX,
                    y:player2.dropY,
                    color:false,
                    fill: true
                }
                flags2[player2.dropX][player2.dropY] = 1;
                lastFlag = fl;
                drawCanvas();
                // 此处设置css
                $$("span.player1").className = "player1 light";
                $$("span.player2").className = "player2";
                can_drop = true;
                droped = false;
                // 请求服务器,去除beatid的已落子
                console.log("请求服务器,去除beatid的已落子");
                poststr = "uname="+username+"&pword="+password+"&q=1&beatuname="+player2.uname;
                console.log(poststr);
            }
        } else {
            // 仍在匹配中,仅轮询
            poststr = "uname="+username+"&pword="+password+"&q=0";
            console.log(poststr);
        }
    } else if(state == "comp") {    // 如果当前正在比赛
        console.log("正在比赛...");
        for(var i=0;i<players.length;i++){
            if(players[i].id == my.beatid){
                player2 = players[i];
                break;
            }
        }
        if(player2.isdrop == 1){    // 如果对方落子
            console.log("对方落子...");
            // 此处设置css
            $$("span.player1").className = "player1 light";
            $$("span.player2").className = "player2";
            fl = {
                x:player2.dropX,
                y:player2.dropY,
                color: false,
                fill: true
            }
            flags2[player2.dropX][player2.dropY] = 1;
            judge_game();
            lastFlag = fl;
            drawCanvas();
            if(win_player == 2){
                // 对方获胜
                console.log("对方获胜");
                $$("strong#dialog_info").innerHTML = "对方获胜";
                show_dialog();
                // 请求服务器,对方获胜
                poststr = "uname="+username+"&pword="+password+"&q=3&beatuname="+player2.uname+"&beatw="+player2.winnum; 
                game_over();
            } else {
                // 请求服务器,去除beatid的已落子
                console.log("请求服务器,去除beatid的已落子");
                poststr = "uname="+username+"&pword="+password+"&q=1&beatuname="+player2.uname;
                can_drop = true;
            }
            console.log(poststr);
        } else if(droped){  // 如果己方落子
            // 请求服务器,增加己方落子信息
            console.log("请求服务器,增加己方落子信息");
            poststr = "uname="+username+"&pword="+password+"&q=2&dropX="+dropX+"&dropY="+dropY;
            console.log(poststr);
            droped = false;
            if(win_player == 1){
                // 己方获胜
                console.log("己方获胜");
                game_over();
                $$("strong#dialog_info").innerHTML = "你赢了!";
                show_dialog();
            }
        } else {
            // 双方均未操作,仅轮询
            poststr = "uname="+username+"&pword="+password+"&q=0";
            console.log(poststr);
            return;
        }
    }
    var xml = new XMLHttpRequest();
    xml.open("POST", "/gobang/gobangstate.php", false);
    xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    console.log(poststr);
    xml.send(poststr);
    var re = xml.responseText;
    console.log(re);
    tp = re;
    // player1 = eval("("+re+")");
    player1 = my;
}
// 10=》10  1=》01
function re_trim(i){
    if(i>=10){
        return i;
    } else {
        return "0" + i;
    }
}
// 开始游戏后,每秒更新时间
function get_time(){
    sec += 1;if(sec == 60){sec = 0;min += 1;}
    $$("span.playtime").innerHTML = re_trim(min) + ":" + re_trim(sec);
}
// 开始新游戏函数
function new_game(){
    min = 0;
    sec = 0;
    initflags();
    drawCanvas();
    player2 = {}
    $$("span.player2").innerHTML = "player2";
    var poststr = "uname=" + username + "&pword=" + password + "&q=4";
    var xml = new XMLHttpRequest();
    xml.open("POST", "/gobang/gobangstate.php", false);
    xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xml.send(poststr);
    var re = xml.responseText;
    console.log(re);
    if(re.split(" ")[0] == "false"){ // 如果出错
        alert(re);
    } else if(re.split(" ")[0] == "true"){ // 情况1,
        state = "wait";
        can_drop = true;
        $$("strong#dialog_info").innerHTML = "连接数据库成功<br>已加入匹配列表!<br>请等待";
        show_dialog();
        get_user_list();
        int_get_info = setInterval(get_info, 1000, false);
    } else { // 情况2,开始对战
        state = "comp";
        can_drop = false;
        player2 = eval(re);
        $$("span.player2").innerHTML = player2.uname;
        sec = 0;min = 0;
        int_get_time = setInterval(get_time, 1000, false);
        int_get_info = setInterval(get_info, 1000, false);
    }
}
// 游戏结束
function game_over(){
    clearInterval(int_get_info);
    clearInterval(int_get_time);
    state = "0";
    // $$("span.player1").className = "player1";
    $$("span.player2").className = "player2";
    $$("span.player1").className = "player1";

}
// 认输
function get_fail(){}
// 登录
function login(){
    if($$("input#uname").value == "" || $$("input#pword").value == ""){
        alert("用户名或密码为空!");
        return ;
    }
    var poststr = "uname=" + $$("input#uname").value + "&pword=" + $$("input#pword").value + "&fun=login";
    var xml = new XMLHttpRequest();
    xml.open("POST", "/gobang/gobanglog.php", false);
    xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xml.send(poststr);
    var re = xml.responseText;
    console.log(re);
    if(re.split(" ")[0] == "false"){
        alert("失败\n"+re[1])
    } else {
        cancel_login();
        $$("button.initlogin").style.display = "none";
        $$("span.player1").innerHTML = $$("input#uname").value;
        username = $$("input#uname").value;
        password = $$("input#pword").value;
        player1.uname = $$("input#uname").value;
        player1 = eval(re);
    }
}
// 获取在线用户列表
function get_user_list(){
    if(!player1.uname){
        alert("用户未登录");
    } else {
        var poststr = "uname=" + username + "&pword=" + password + "&fun=userlist";
        var xml = new XMLHttpRequest();
        xml.open("POST", "/gobang/gobanglog.php", false);
        xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xml.send(poststr);
        var re = xml.responseText;
        players = eval(re);
        console.log(re);
        var ih = "";
        for(var i=0;i<players.length;i++){
            ih += "<tr><td>"+players[i].id+"</td><td>"+players[i].uname+"</td><td>"+["否", "是"][players[i].iscomp]+"</td><td>"+["否", "是"][players[i].waitting]+"</td><td>"+players[i].beatid+"</td><td>"+players[i].winnum+"</td><td>"+players[i].lostnum+"</td><td>"+players[i].tienum+"</td></tr>";
        }
        $$("div.user-list").style.display = "block";
        $$("tbody.users").innerHTML = ih;
    }
}
// 登出
function logout(){
    if(!player1.uname){
        alert("用户未登录,无法登出");
    } else {
        var poststr = "uname=" + username + "&pword=" + password + "&fun=logout";
        var xml = new XMLHttpRequest();
        xml.open("POST", "/gobang/gobanglog.php", false);
        xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xml.send(poststr);
        var re = xml.responseText;
        if(re == "true"){
            username = "";
            password = "";
            if(state == "comp"){
                state = "0";
                game_over();
            }
            alert("登出成功");
            $$("button.initlogin").style.display = "block";
            player1 = {};
            player2 = {};
            players = [];
            drawCanvas();
            clearInterval(int_get_info);
            clearInterval(int_get_time);
            $$("span.player1").innerHTML = "player1";
            $$("span.player2").innerHTML = "player2";
            $$("div.user-list").style.display = "none";
            $$("span.playtime").innerHTML = "00:00";
        } else {
            alert("登出失败\n"+re);
        }
    }
}
function load(){
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas, false);
    // $$("canvas").addEventListener('mousedown', mouseDownHandler, false);
}
var canvas = $$("canvas");
var context = canvas.getContext("2d");
var minLen = 0;     // 浏览器长度和宽度中较小的那个
var dlength = 0;    // 除去两侧边框后的长度
var step = 0;       // 线间隔,单位px
var num = 15;       // 横线、竖线数
var cX = (num-1)/2; // 中心棋子x坐标
var cY = (num-1)/2; // 中心棋子y坐标
var flagR = 10;     // 棋子半径
var border_len = 20; // 边框大小,单位px
var selected = false;// 是否选中,处理以后写
var dropX = 0;    // 落子x坐标
var dropY = 0;    // 落子y坐标
// var flags = [];   // 储存棋子信息
var flags1 = [];    //储存玩家1棋子信息
var flags2 = [];    //储存玩家2棋子信息
function init_flags(){
    // 初始化
    for(var i=0;i<num;i++){
        var tpp1 = [];
        var tpp2 = [];
        for(var j=0;j<num;j++){
            tpp1.push(0);
            tpp2.push(0);
        }
        flags1.push(tpp1);
        flags2.push(tpp2);
    }
}
init_flags();
function initflags(){
    for(var i=0;i<num;i++){
        for(var j=0;j<num;j++){
            flags1[i][j] = 0;
            flags2[i][j] = 0;
        }
    }
}
var flag = "|";   // 判断竖屏和横屏,处理以后写,
var player1 = {}; // 玩家1(self)
var player2 = {}; // 玩家2(对战对象)
var players = {}; // 所有在线玩家
var state = "0";  // 状态
var username = "";// 自己的用户名
var password = "";// 自己的密码
var sec = 0;      // 秒数
var min = 0;      // 分钟数
var can_drop = false;// 当前是否可以落子
var droped = false;  // 是否已落子
var int_get_user_list;// 此三个,对应定时器
var int_get_info;
var int_get_time;
var my = {};        // 储存自己信息
var tp = {};        // 储存返回信息,便于控制台调试
var lastFlag = {};  // 储存最后一颗棋子的信息
var win_player = 0; // 储存谁赢了,都没赢为0
var isOk = false;   // 用于确认下棋
// 处理窗口大小改变
function resizeCanvas() {
    // 浏览器长度和宽度中较小的那个
    minLen = Math.min(window.innerWidth,window.innerHeight);
    // 判断竖屏或横屏
    if(minLen == window.innerWidth){
        flag = "|";
    } else {
        flag = "-";
    }
	canvas.width = minLen;
	canvas.height = minLen;
	dlength = minLen - border_len*2;
	step = dlength/(num-1);
	flagR = step/3;
	drawCanvas();
}
// 绘制canvas
function drawCanvas() {
    // 背景色
	context.fillStyle = 'rgb(249,241,91)';
    context.fillRect(0,0,canvas.width, canvas.height);
    // 绘制横竖线
	var i = 0;
	for(i=0;i<num;i++) {
		context.moveTo(border_len+i*step, border_len);
		context.lineTo(border_len+i*step, border_len+dlength);
		context.moveTo(border_len, border_len+i*step);
		context.lineTo(border_len+dlength,border_len+i*step);
	}
	context.stroke();
    // 绘制五个小黑点
	drawFlag(cX,cY,step/10,true);
	drawFlag(cX-4,cY-4,step/10,true);
	drawFlag(cX+4,cY-4,step/10,true);
	drawFlag(cX-4,cY+4,step/10,true);
	drawFlag(cX+4,cY+4,step/10,true);
    drawAllFlags();
    // 重绘(着重提醒)最后落下的棋子
    drawFlag3(lastFlag);
}
// 绘制canvas2
function drawAllFlags() {
    for(var i=0;i<num;i++){
        for(var j=0;j<num;j++){
            if(flags1[i][j] == 1){
                drawFlag(i,j,flagR,true);
            } else if(flags2[i][j] == 1){
                drawFlag(i,j,flagR,false);
            }
        }
    }
}
// 棋子绘制函数(棋子x坐标,棋子y坐标,棋子半径,棋子颜色)
function drawFlag(x,y,r,color) {
    // color=ture表示黑色
	if(color) {
		context.fillStyle = "#000";
	} else {
		context.fillStyle = "#fff";
	}
	context.beginPath();
	context.arc(border_len+x*step,border_len+y*step,r,0,Math.PI*2,true);
	context.closePath();
    context.stroke();
	context.fill();
}
// 棋子绘制函数3
function drawFlag3(fl){
    if(fl.color) {
		context.fillStyle = "#000";
	} else {
		context.fillStyle = "#fff";
	}
    if(!fl.fill){
        context.fillStyle = "#f0f"
    }
    context.strokeStyle = "#ff0000";
    context.beginPath();
	context.arc(border_len+fl.x*step,border_len+fl.y*step,flagR,0,Math.PI*2,true);
	context.closePath();
    context.stroke();
    context.fill();
    
    context.strokeStyle = "#000000";
}
// 处理鼠标点击事件
// function mouseDownHandler(e){
$("canvas").mousedown(function (e){
    // 如果当前可以落子
    if(can_drop){
        // 获取落子的x,y坐标,并输出
        var tdropX = parseInt((e.clientX-border_len+step/2)/step);
        var tdropY = parseInt((e.clientY-55-border_len+step/2)/step);
        console.log(tdropX, tdropY);
        // // 判断该处是否已有棋子
        if((flags1[tdropX][tdropY] == 0) && (flags2[tdropX][tdropY] == 0)){
            if(isOk){
                if(lastFlag.x == tdropX && lastFlag.y == tdropY){
                    lastFlag.fill = true;
                    dropX = tdropX;
                    dropY = tdropY;
                    flags1[dropX][dropY] = 1;
                    judge_game();
                    drawCanvas();
                    // 此处设置对方css
                    // $$("span.player1").toggleClass("light");
                    // $$("span.player2").toggleClass("light");
                    $$("span.player1").className = "player1";
                    $$("span.player2").className = "player2 light";
                    // 更新状态
                    droped = true;
                    can_drop = false;
                    isOk = false;
                } else {
                    var fl = {
                        x:tdropX,
                        y:tdropY,
                        color:true,
                        fill:false
                    }
                    lastFlag = fl;
                } 
            } else {
                var fl = {
                    x:tdropX,
                    y:tdropY,
                    color:true,
                    fill:false
                }
                lastFlag = fl;
                isOk = true;
            }
        }
        drawCanvas();
    }
// }
})
// 输赢判断:下面5个函数
function judge_row(flags_){
    for(var i=0;i<num-4;i++){
        for(var j=0;j<num;j++){
            if(flags_[i][j] == 1){
                if(flags_[i+1][j] == 1){
                    if(flags_[i+2][j] == 1){
                        if(flags_[i+3][j] == 1){
                            if(flags_[i+4][j] == 1){
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}
function judge_col(flags_){
    for(var i=0;i<num;i++){
        for(var j=0;j<num-4;j++){
            if(flags_[i][j] == 1){
                if(flags_[i][j+1] == 1){
                    if(flags_[i][j+2] == 1){
                        if(flags_[i][j+3] == 1){
                            if(flags_[i][j+4] == 1){
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}
function judge_leftTop(flags_){
    for(var i=0;i<num-4;i++){
        for(var j=0;j<num-4;j++){
            if(flags_[i][j] == 1){
                if(flags_[i+1][j+1] == 1){
                    if(flags_[i+2][j+2] == 1){
                        if(flags_[i+3][j+3] == 1){
                            if(flags_[i+4][j+4] == 1){
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}
function judge_rightTop(flags_){
    for(var i=num-1;i>5;i--){
        for(var j=0;j<num-4;j++){
            if(flags_[i][j] == 1){
                if(flags_[i-1][j+1] == 1){
                    if(flags_[i-2][j+2] == 1){
                        if(flags_[i-3][j+3] == 1){
                            if(flags_[i-4][j+4] == 1){
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}
function judge_game(){
    if(judge_row(flags1) || judge_col(flags1) || judge_leftTop(flags1) || judge_rightTop(flags1)){
        // 玩家1获胜
        win_player = 1;
        return 1;
    } else if(judge_row(flags2) || judge_col(flags2) || judge_leftTop(flags2) || judge_rightTop(flags2)){
        // 玩家2获胜
        win_player = 2;
        return 2;
    } else {
        // 均未获胜
        win_player = 0;
        return 0;
    }
}
var mouse = {};
mouse.x_base = $("div.dialog").css('top');
mouse.y_base = $("div.dialog").css('left');
var dialog = $$("div.dialog");
function close_dialog(){// 关闭弹窗
    // dialog.style.opacity = "0.0";
    dialog.style.display = "none";
    dialog.style.top = mouse.x_base;
    dialog.style.left = mouse.y_base;
};
function show_dialog(){// 显示弹窗
    dialog.style.opacity = 1.0;
    dialog.style.display = "block";
};
// 弹窗移动相关
function moveDialog(event) {
    // var e = window.event || event;
    var e = event;
    // console.log(e.clientX, e.clientY);
    dialog.style.top = parseInt($("div.dialog").css('top')) + (e.clientY - mouse.y) + "px";
    dialog.style.left = parseInt($("div.dialog").css('left')) + (e.clientX - mouse.x) + "px";
    mouse.x = e.clientX;
    mouse.y = e.clientY;
};
$(".main>.dialog>.bar").mousedown(function(event) {
    var e = window.event || event;
    mouse.x = e.clientX;
    mouse.y = e.clientY;
    dialog.className = "dialog selected";
    // console.log("bind");
    $(document).bind('mousemove', moveDialog);
});
$(".main>.dialog>.bar").mouseup(function(event) {
    dialog.className = "dialog";
    // console.log("unbind");
    $(document).unbind('mousemove', moveDialog);
});

数据库相关

desc myweb.gobanguser

create database if not exists myweb;
use myweb;
create table if not exists gobanguser(
id tinyint(1) unsigned not null auto_increment,
uname varchar(20) not null,
pword varchar(20),
isol boolean default 0,
iscomp boolean default 0,
waitting boolean default 0,
beatid tinyint(1) unsigned default 1,
isdrop boolean default 0,
begintime datetime default current_timestamp,
lastlogin datetime default current_timestamp,
winnum tinyint(2) unsigned default 0,
lostnum tinyint(2) unsigned default 0,
tienum tinyint(2) unsigned default 0,
dropX tinyint(1) default 0,
dropY tinyint(1) default 0,
logIP varchar(15) default "0.0.0.0",
primary key(id, uname)
)default charset=utf8;

gobanglog.php

请将第三行处修改为自己数据库的相关信息,下一个文件也是

<?php
$ip = $_SERVER["REMOTE_ADDR"];
$con = new mysqli("localhost", "用户名", "用户密码", "数据库名");
if(!$con){
    die("false 数据库连接失败,暂时无法登录");
}
$uname = $_POST["uname"];
$pword = $_POST["pword"];
$fun = $_POST["fun"];
$result = $con->query("select * from gobanguser where uname='".$uname."';");
if($result->num_rows > 0){
    $row = $result->fetch_assoc();
    if($row["pword"] == $pword){
        if($fun == "login"){
            if($row["isol"] == "1"){
                die("false 禁止重复登录");
            } else {
                login_return($row);
            }
        } elseif ($fun == "logout") {
            if($row["isol"] == "0"){
                die("false 禁止重复登出");
            } else {
                logout_return($row);
            }
        } elseif ($fun == "userlist"){
            if($row["isol"] == "1"){
                userlist_return();
            } else {
                die("false 用户未登录");
                
            }
        }
        
    } else {
        $con->close();
        die("false 密码错误");
    }
} else {
    $con->close();
    die("false 无此用户");
}
function login_return($row){
    $str = "({";
    $id = $row["id"];
    global $uname,$con,$ip;
    foreach($row as $key => $val){
        if($key != "pword"){
            $str = $str."$key:'$val',";
        }
    }    
    if($con->query("update gobanguser set isol=1,lastlogin=now(),logIP='".$ip."' where uname=\"".$uname."\" and id=".$id)){
        $con->commit();
        echo substr($str,0,-1)."})";
    } else {
        $con->close();
        die("false 数据库更新失败");
    }
    $con->close();
}
function logout_return($row){
    $id = $row["id"];
    global $uname,$con;
    if($con->query("update gobanguser set isol=0,lastlogout=now() where uname=\"".$uname."\" and id=".$id)){
        // $con->commit();
        echo "true";
    } else {
        $con->close();
        die("false 数据库更新失败");
    }
    $con->close();
}
function userlist_return(){
    $str = "[{";
    global $con;
    $result = $con->query("select id,uname,iscomp,waitting,beatid,isdrop,winnum,lostnum,tienum,dropX,dropY from myweb.gobanguser where isol!=0");
    if($result){
        while($row=$result->fetch_assoc()){
            foreach($row as $key => $val){
                $str = $str."$key:'$val',";
            }
            $str = $str."},{";
        }
        echo substr($str,0,-2)."]";
    } else {
        $con->close();
        die("false 查询数据库失败");
    }
    $con->close();
}
?>

gobangstate.php

<?php
$ip = $_SERVER["REMOTE_ADDR"];
$con = new mysqli("localhost", "用户名", "用户密码", "数据库名");
if(!$con){
    die("false 数据库连接失败,暂时无法登录");
}
$uname = $_POST["uname"];
$pword = $_POST["pword"];
$q = $_POST["q"];
$result = $con->query("select * from gobanguser where uname='".$uname."';");
if($result->num_rows > 0){
    $row = $result->fetch_assoc();
    if($row["pword"] == $pword){
        if($row["isol"] == "0"){
            die("false 用户未登录");
        } else {
            if($q == "0"){
                // 轮询
            } elseif ($q == "1"){
                update_fun("update gobanguser set isdrop=0,dropX=0,dropY=0 where id=".$row["beatid"]." and uname='".$_POST["beatuname"]."'", true);
            } elseif ($q == "2"){
                update_fun("update gobanguser set isdrop=1,dropX=".$_POST["dropX"].",dropY=".$_POST["dropY"]." where id=".$row["id"]." and uname='".$row["uname"]."'", true);
            } elseif ($q == "3"){
                update_fun("update gobanguser set isdrop=0,dropX=0,dropY=0,iscomp=0,beatid=0,winnum=".(intval($_POST["beatw"])+1)." where id=".$row["beatid"]." and uname='".$_POST["beatuname"]."'", false);
                update_fun("update gobanguser set isdrop=0,dropX=0,dropY=0,iscomp=0,beatid=0,lostnum=".(intval($row["lostnum"])+1)." where id=".$row["id"]." and uname='".$row["uname"]."'", true);
            } elseif ($q == "4"){
                new_game($row);
            }
        }
    } else {
        $con->close();
        die("false 密码错误");
    }
} else {
    $con->close();
    die("false 无此用户");
}
function update_fun($str, $end){
    echo $str;
    global $con;
    if(!$con->query($str)){
        echo "false 数据库更新失败";
    }
    if($end){
        $con->close();
    }
}
function new_game($row){
    global $con;
    $result1 = $con->query("select id,uname,iscomp,waitting,beatid,isdrop,winnum,lostnum,tienum,dropX,dropY from gobanguser where waitting != 0 and iscomp!=1");
    if($result1->num_rows > 0){
        $row1 = $result1->fetch_assoc();
        if($con->query("update gobanguser set waitting=0,iscomp=1,beatid=".$row["id"]." where uname='".$row1["uname"]."' and id=".$row1["id"])){
            if($con->query("update gobanguser set iscomp=1,beatid=".$row1["id"]." where uname='".$row["uname"]."' and id=".$row["id"])){
                $str = "({";
                foreach($row1 as $key => $val){
                    $str = $str."$key:'$val',";
                }
                echo substr($str,0,-1)."})";
                $con->close();
            } else {
                $con->close();
                die("false 数据库更新失败");
            }
        } else {
            $con->close();
            die("false 数据库更新失败");
        }
    } else {
        if($con->query("update gobanguser set waitting=1 where uname='".$row["uname"]."' and id=".$row["id"])){
            echo "true waitting";
            $con->close();
        } else {
            $con->close();
            die("false 数据库更新失败");
        }
    }
}
?>

版本:
php : php-8.1.2-Win32-vs16-x86
Apache : httpd-2.4.52-o111m-x86-vc15
MySql : 8.0.28

发现的错误和一些建议欢迎评论

参考:
php官方文档(mysqli相关) https://www.php.net/manual/zh/book.mysqli.php
兰州大学官网 对话框相关 http://www.lzu.edu.cn/res/js/dialog.js
菜鸟教程 PHP连接数据库相关 https://www.runoob.com/php/php-mysql-connect.html
PHP语言的强制类型转换 https://www.php.cn/php-ask-460606.html
PHP substr() 字符串切割函数 https://www.w3cschool.cn/php/func-string-substr.html
php中mysqli 处理查询结果集的几个方法 https://www.cnblogs.com/lizhaoyao/p/4863476.html
PHP获取用户访问IP地址的5种方法 https://www.jb51.net/article/84338.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今夕何夕2112

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值