一、下载安装workman,地址:https://github.com/walkor/workerman

composer require workerman/workerman

二、cd到workerman项目根目录下,在workerman根目录下新建game.php,然后编写五子棋服务端交互代码

<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php'; $global_uid = 0;
//棋盘大小,默认15行15列
$global_i = 15;
$global_j = 15; // 当客户端连上来时分配uid
function handle_connection($connection)
{
global $text_worker, $global_uid, $global_i, $global_j;
// 为这个链接分配一个uid
$connection->uid = ++$global_uid;
$text_worker->uidConnections[$connection->uid] = array('cons' => $connection);
$text_worker->user_data[$connection->uid] = array('playing' => 0, 'name' => '玩家' . $connection->uid, 'qipan' => array(), 'type' => 0, 'move' => 0);
$json = array('status' => 1, 'msg' => '', 'data' => array());
$json['data']['name'] = $text_worker->user_data[$connection->uid]['name'];
$connection->send(json_encode($json)); //生成玩家昵称
echo "player {$connection->uid} connected!\n";
//分配对手
foreach ($text_worker->user_data as $k => $val) {
/*var_dump($val['playing']);*/
if ($val['playing'] == 0 && $k != $connection->uid) {
//初始化棋盘
$init_data = array();
for ($i = 0; $i <= $global_i; $i++) {
for ($j = 0; $j <= $global_j; $j++) {
$init_data[$i][$j] = 0;
}
}
$text_worker->user_data[$k]['qipan'] = $init_data;
$text_worker->user_data[$connection->uid]['qipan'] = $init_data;
$text_worker->user_data[$k]['playing'] = $connection->uid;
$text_worker->user_data[$connection->uid]['playing'] = $k; //分配红黑方
$text_worker->user_data[$k]['type'] = 1;
$text_worker->user_data[$k]['move'] = 1;
$text_worker->user_data[$connection->uid]['type'] = 2;
$text_worker->user_data[$connection->uid]['move'] = 0;
$json = array('status' => 2, 'msg' => '初始化棋盘...', 'data' => array());
$json['data']['qipan'] = $init_data;
$text_worker->uidConnections[$k]['cons']->send("为你匹配到对手{$text_worker->user_data[$connection->uid]['name']}!");
$text_worker->uidConnections[$connection->uid]['cons']->send("为你匹配到对手{$val['name']}!"); break;
}
} /*var_dump($text_worker->user_data);*/
} // 当客户端发送消息过来时
function handle_message($connection, $data)
{
global $text_worker, $global_i, $global_j;
$data = json_decode($data, true); if ($data['status'] == 2 && $text_worker->user_data[$connection->uid]['playing'] > 0 && $text_worker->user_data[$connection->uid]['move'] == 1) {
$my_uid = $connection->uid;
$your_uid = $text_worker->user_data[$my_uid]['playing'];
$qipan = $text_worker->user_data[$your_uid]['qipan'];
$press = explode('_', $data['data']);
array_shift($press); if (!empty($press)) {
$press_val = $qipan[$press[0]][$press[1]];
if ($press_val != 0) {
return;
} else {
$qipan[$press[0]][$press[1]] = $text_worker->user_data[$my_uid]['type'];
$text_worker->user_data[$my_uid]['qipan'] = $qipan;
$text_worker->user_data[$your_uid]['qipan'] = $qipan;
$text_worker->user_data[$your_uid]['move'] = 1;
$text_worker->user_data[$my_uid]['move'] = 0;
$json = array('status' => 2, 'msg' => '', 'data' => array());
$json['data']['type'] = $text_worker->user_data[$my_uid]['type'];
$json['data']['press_i'] = $press[0];
$json['data']['press_j'] = $press[1];
$text_worker->uidConnections[$my_uid]['cons']->send(json_encode($json));
$text_worker->uidConnections[$your_uid]['cons']->send(json_encode($json));
$count = get_who_win($qipan, $press[0], $press[1], $text_worker->user_data[$my_uid]['type'], $global_i, $global_j);
file_put_contents('./qipan', json_encode($qipan));
if ($count >= 5) { //分出胜负
$json = array('status' => 3, 'msg' => $text_worker->user_data[$my_uid]['name'] . ' 获胜 !', 'data' => array());
$json['data']['type'] = $text_worker->user_data[$my_uid]['type'];
$text_worker->uidConnections[$my_uid]['cons']->send(json_encode($json));
$text_worker->uidConnections[$your_uid]['cons']->send(json_encode($json));
}
}
}
}
} // 当客户端断开时,广播给所有客户端
function handle_close($connection)
{
global $text_worker;
/*foreach ($text_worker->connections as $conn) {
$conn->send("user[{$connection->uid}] logout");
}*/
} /**
* 判断输赢
* $qipan 棋盘数据
* $i 下子时的横坐标
* $i 下子时的纵坐标
* $type 1黑方 2红方
* $global_i 棋盘边界值
* $global_j 棋盘边界值
*/
function get_who_win($qipan = array(), $i = -1, $j = -1, $type = 0, $global_i = 0, $global_j = 0)
{
$count = 0;
$temp_type = $type;
if (empty($qipan) || $i < 0 || $j < 0 || $type <= 0) {
return $count;
}
echo json_encode($qipan) . "\n";
echo 'i=' . $i . '|j=' . $j . '|type=' . $type . '|gi=' . $global_i . '|gj=' . $global_j . "\n";
/*左右上下的判断*/
$count = 1;
$a = array(
0 => array('index' => $j, 'border' => $global_j), //左右,
1 => array('index' => $i, 'border' => $global_i) //上下
); for ($round = 0; $round <= 1; $round++) {
$mov1_num = 1;
$mov2_num = 1;
while (true) {
$mov1 = $a[$round]['index'] + $mov1_num;
$mov2 = $a[$round]['index'] - $mov2_num;
$temp_mov1 = $temp_mov2 = -1;
if ($mov1_num > 0) {
if ($round == 0 && $mov1 <= $global_j) {
$temp_mov1 = $qipan[$i][$mov1];
var_dump($i . ',' . $mov1 . ',' . $temp_mov1);
} elseif ($round == 1 && $mov1 <= $global_i) {
$temp_mov1 = $qipan[$mov1][$j];
} if ($temp_mov1 == $temp_type) {
$count++;
var_dump('count=' . $count);
$mov1_num++;
} else {
$mov1_num = 0;
}
} else {
$mov1_num = 0;
} if ($mov2 >= 0 && $mov2_num > 0) {
if ($round == 0) {
$temp_mov2 = $qipan[$i][$mov2];
var_dump($i . ',' . $mov2 . ',' . $temp_mov1);
} elseif ($round == 1) {
$temp_mov2 = $qipan[$mov2][$j];
} if ($temp_mov2 == $temp_type) {
$count++;
$mov2_num++;
} else {
$mov2_num = 0;
}
} else {
$mov2_num = 0;
} if ($count >= 5) {
return $count;
} if (($mov1_num == 0 && $mov2_num == 0)) {
break;
}
}
} /*斜角的判断*/ $count = 1;
for ($round = 0; $round <= 1; $round++) {
$mov1_num = 1;
$mov2_num = 1; while (true) {
$temp_mov1 = $temp_mov2 = -1;
if (($i - $mov1_num) >= 0 && ($j - $mov1_num) >= 0 && ($j + $mov1_num) <= $global_j && $mov1_num > 0) {
if ($round == 0) {
$temp_mov1 = $qipan[$i - $mov1_num][$j + $mov1_num];
} elseif ($round == 1) {
$temp_mov1 = $qipan[$i - $mov1_num][$j - $mov1_num];
} if ($temp_mov1 == $temp_type) {
$count++;
$mov1_num++;
} else {
$mov1_num = 0;
}
} else {
$mov1_num = 0;
} if (($i + $mov2_num) <= $global_i && ($j - $mov2_num) >= 0 && ($j + $mov2_num) <= $global_j && $mov2_num > 0) {
if ($round == 0) {
$temp_mov2 = $qipan[$i + $mov2_num][$j - $mov2_num];
} elseif ($round == 1) {
$temp_mov2 = $qipan[$i + $mov2_num][$j + $mov2_num];
} if ($temp_mov2 == $temp_type) {
$count++;
$mov2_num++;
} else {
$mov2_num = 0;
}
} else {
$mov2_num = 0;
} if ($count >= 5) {
return $count;
} if (($mov1_num == 0 && $mov2_num == 0)) {
break;
}
}
}
return $count;
} // 创建一个文本协议的Worker监听2347接口 $text_worker = new Worker("websocket://0.0.0.0:2347");
// 只启动1个进程
$text_worker->count = 1;
$text_worker->uidConnections = array();
$text_worker->user_data = array();
$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';
Worker::runAll();

三、编写前端代码,这里保存为index.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<style type="text/css">
td{
width:30px;
height:30px;
border:1px solid #666;
}
table{
border-collapse: collapse;
border-spacing: 0;
}
</style>
</head> <body>
<div class="player"></div>
<div id="demo"></div>
</body> </html> <script>
table = "<table>";
for (let i = 0; i <= 15; i++) {
table += "<tr>";
for (let j = 0; j <= 15; j++) {
table += "<td onclick='press_on(this)' id='div_" + i + "_" + j + "'>" + "</td>";
}
table += "</tr>";
}
table += "</table>";
$('#demo').html(table); ws = new WebSocket("ws://127.0.0.1:2347");
ws.onopen = function () {
console.log("连接成功");
}; ws.onmessage = function (e) {
//alert("收到服务端的消息:" + e.data);
console.log(e.data);
var jsonobj = eval('(' + e.data + ')');
if (jsonobj.status == 1 && jsonobj.data.name != null) {//初始化名字
alert(jsonobj.data.name);
$('.player').html(jsonobj.data.name);
} if (jsonobj.status == 2) {//
var type = jsonobj.data.type;
var press_i = jsonobj.data.press_i;
var press_j = jsonobj.data.press_j;
id = '#div_' + press_i + '_' + press_j;
$(id).unbind("click");
if (type == 1) {
$(id).html("<div style='background:#000000;width:30px;height:30px;border-radius:50%;'></div>");
}
if (type == 2) {
$(id).html("<div style='background:#ffbc00;width:30px;height:30px;border-radius:50%;'></div>");
}
} if (jsonobj.status == 3) {//
var msg = jsonobj.msg;
var r = confirm(msg + ',是否从新开始?');
if (r) {
window.location.reload(true);
return;
} else {
return;
}
}
}; function press_on(value) {
var send = '{"status":2,"data":"' + value.id + '"}';
console.log(send);
ws.send(send);
}
</script>

四、运行

在命令行启动服务器php game.php

最后在浏览器地址访问index.html,进入游戏。

转载自https://blog.csdn.net/weixin_33971205/article/details/92266560

workman在线五子棋的更多相关文章

  1. jquery在线五子棋

    在线五子棋试玩地址:http://keleyi.com/game/12/ 以下是完整代码,保存到html文件打开也可以玩: <!DOCTYPE html> <html> < ...

  2. js+html5双人五子棋(源码下载)

    代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...

  3. aTool在线工具

    在线HTTP POST/GET接口测试工具 - aTool在线工具 地址:http://www.atool.org/httptest.php在线接口测试工具接口测试是测试系统组件间接口的一种测试.接口 ...

  4. Web前端资源汇总

    本文地址:http://www.cnblogs.com/jihua/p/webfront.html 网页特效库 2017新年快乐特效 CSS3+jQuery实现时钟插件 Html5入门实例" ...

  5. 仿腾讯QQ竖直滑动导航菜单

    菜单就像qq软件的分组,鼠标经过自动显示相应组的内容. 效果体验网址:http://keleyi.com/a/bjad/nf86w2dv.htm 以下是源代码: <html> <he ...

  6. jQuery弹出窗口完整代码

    jQuery弹出窗口完整代码 效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/1.htm 1 <!DOCTYPE html PUBLIC "- ...

  7. WC 2018/CTSC 2018/APIO 2018 游记

    (要写CTSC的时候才想起来没写WC2018,那就粗略回顾一下吧hhhhh) WC 2018(简略版): 大概和 一个宁夏和一个天津的大哥一个宿舍hhhh,字典序分宿舍真是奇妙. WC讲课真的不是人听 ...

  8. 从零开始完整开发基于websocket的在线对弈游戏【五子棋】,只用几十行代码完成全部逻辑。

    五子棋是规则简单明了的策略型游戏,先形成五子连线者获胜.本课程习作采用两人在线对弈的方式进行比赛,拿着手机在上下班路上玩特别合适. 整个过程在众触低代码应用平台进行,使用表达式描述游戏逻辑(高度简化版 ...

  9. 自己写的HTML5 Canvas + Javascript五子棋

    看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本.样式,帮助大众,成为受欢迎的人,感觉满羡慕的.我也想学会前端技术,变得受欢迎呀.于是心血来潮,开始学习前端知识,并写下了这 ...

  10. 完全自制的五子棋人机对战游戏(VC++实现)

    五子棋工作文档 1说明: 这个程序在创建初期的时候是有一个写的比较乱的文档的,但是很可惜回学校的时候没有带回来……所以现在赶紧整理一下,不然再过一段时间就忘干净了. 最初这个程序是受老同学所托做的,一 ...

随机推荐

  1. 利用gost实现pptp转socks5或http代理

    利用gost实现pptp转socks5或http代理 以debian10为例 1.安装pptp服务器端 sudo apt-get install pptpd #debian系统 编辑/etc/pptp ...

  2. 基于Kubernetes的Serverless PaaS稳定性建设万字总结

    作者:许成铭(竞霄) 数字经济的今天,云计算俨然已经作为基础设施融入到人们的日常生活中,稳定性作为云产品的基本要求,研发人员的技术底线,其不仅仅是文档里承诺的几个九的 SLA 数字,更是与客户切身利益 ...

  3. d3条形图案例

  4. 小白学标准库之 http

    1. 前言 标准库是工具,是手段,是拿来用的.一味的学标准库就忽视了语言的内核,关键.语言层面的特性,内存管理,垃圾回收.数据结构,设计模式.这些是程序的内核,要熟练,乃至精通它们,而不是精通标准库. ...

  5. cs 保研经验贴 | 数学试题 · 自动化所特供版

    据(2022 年我所看的)往年经验,自动化所比较重视数学. 感觉,按照自动化所的数学题库复习,就足以应付大多数夏令营的笔试面试了. 目录 高等数学 线性代数 概率论 机器学习 复变函数 其他 同站相关 ...

  6. idea侧边栏commit消失

    1.问题 在使用Clion中想要查看提交的相关信息,发现侧边栏commit消失 2.解决方法 打开设置,选择会用非模式提交界面即可

  7. Laravel - Eloquent 更新数据

    public function ormUpdate()     {         # 1.通过模型更新数据        /*  $student = Student::find(14);      ...

  8. [转帖]OS、PFS、DFS 有啥区别?一文搞懂 6 大临床试验终点

    https://oncol.dxy.cn/article/670607 说到肿瘤临床研究,就不得不说临床试验终点(End Point),比如大家熟知的 OS.PFS.ORR 还有 DFS.TTP.TT ...

  9. Oracle19c 多字符集支持的PDB

    Oracle19c 多字符集支持的PDB 背景 想在一个数据库里面支持多种字符集 突然发现Oracle12c开始已经可以实现一个CDB下面可以有多个不同字符集的PDB了 所以想着今天验证一下. 环境信 ...

  10. [转帖]【Kafka】Kafka配置参数详解

    Kafka配置参数详解 Kafka得安装与基本命令 Kafka配置参数 kafka生产者配置参数 kafka消费者配置参数 本篇文章只是做一个转载的作用以方便自己的阅读,文章主要转载于: Kafka核 ...