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

  1. composer require workerman/workerman

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

  1. <?php
  2. use Workerman\Worker;
  3. require_once __DIR__ . '/vendor/autoload.php';
  4. $global_uid = 0;
  5. //棋盘大小,默认15行15列
  6. $global_i = 15;
  7. $global_j = 15;
  8. // 当客户端连上来时分配uid
  9. function handle_connection($connection)
  10. {
  11. global $text_worker, $global_uid, $global_i, $global_j;
  12. // 为这个链接分配一个uid
  13. $connection->uid = ++$global_uid;
  14. $text_worker->uidConnections[$connection->uid] = array('cons' => $connection);
  15. $text_worker->user_data[$connection->uid] = array('playing' => 0, 'name' => '玩家' . $connection->uid, 'qipan' => array(), 'type' => 0, 'move' => 0);
  16. $json = array('status' => 1, 'msg' => '', 'data' => array());
  17. $json['data']['name'] = $text_worker->user_data[$connection->uid]['name'];
  18. $connection->send(json_encode($json)); //生成玩家昵称
  19. echo "player {$connection->uid} connected!\n";
  20. //分配对手
  21. foreach ($text_worker->user_data as $k => $val) {
  22. /*var_dump($val['playing']);*/
  23. if ($val['playing'] == 0 && $k != $connection->uid) {
  24. //初始化棋盘
  25. $init_data = array();
  26. for ($i = 0; $i <= $global_i; $i++) {
  27. for ($j = 0; $j <= $global_j; $j++) {
  28. $init_data[$i][$j] = 0;
  29. }
  30. }
  31. $text_worker->user_data[$k]['qipan'] = $init_data;
  32. $text_worker->user_data[$connection->uid]['qipan'] = $init_data;
  33. $text_worker->user_data[$k]['playing'] = $connection->uid;
  34. $text_worker->user_data[$connection->uid]['playing'] = $k;
  35. //分配红黑方
  36. $text_worker->user_data[$k]['type'] = 1;
  37. $text_worker->user_data[$k]['move'] = 1;
  38. $text_worker->user_data[$connection->uid]['type'] = 2;
  39. $text_worker->user_data[$connection->uid]['move'] = 0;
  40. $json = array('status' => 2, 'msg' => '初始化棋盘...', 'data' => array());
  41. $json['data']['qipan'] = $init_data;
  42. $text_worker->uidConnections[$k]['cons']->send("为你匹配到对手{$text_worker->user_data[$connection->uid]['name']}!");
  43. $text_worker->uidConnections[$connection->uid]['cons']->send("为你匹配到对手{$val['name']}!");
  44. break;
  45. }
  46. }
  47. /*var_dump($text_worker->user_data);*/
  48. }
  49. // 当客户端发送消息过来时
  50. function handle_message($connection, $data)
  51. {
  52. global $text_worker, $global_i, $global_j;
  53. $data = json_decode($data, true);
  54. if ($data['status'] == 2 && $text_worker->user_data[$connection->uid]['playing'] > 0 && $text_worker->user_data[$connection->uid]['move'] == 1) {
  55. $my_uid = $connection->uid;
  56. $your_uid = $text_worker->user_data[$my_uid]['playing'];
  57. $qipan = $text_worker->user_data[$your_uid]['qipan'];
  58. $press = explode('_', $data['data']);
  59. array_shift($press);
  60. if (!empty($press)) {
  61. $press_val = $qipan[$press[0]][$press[1]];
  62. if ($press_val != 0) {
  63. return;
  64. } else {
  65. $qipan[$press[0]][$press[1]] = $text_worker->user_data[$my_uid]['type'];
  66. $text_worker->user_data[$my_uid]['qipan'] = $qipan;
  67. $text_worker->user_data[$your_uid]['qipan'] = $qipan;
  68. $text_worker->user_data[$your_uid]['move'] = 1;
  69. $text_worker->user_data[$my_uid]['move'] = 0;
  70. $json = array('status' => 2, 'msg' => '', 'data' => array());
  71. $json['data']['type'] = $text_worker->user_data[$my_uid]['type'];
  72. $json['data']['press_i'] = $press[0];
  73. $json['data']['press_j'] = $press[1];
  74. $text_worker->uidConnections[$my_uid]['cons']->send(json_encode($json));
  75. $text_worker->uidConnections[$your_uid]['cons']->send(json_encode($json));
  76. $count = get_who_win($qipan, $press[0], $press[1], $text_worker->user_data[$my_uid]['type'], $global_i, $global_j);
  77. file_put_contents('./qipan', json_encode($qipan));
  78. if ($count >= 5) { //分出胜负
  79. $json = array('status' => 3, 'msg' => $text_worker->user_data[$my_uid]['name'] . ' 获胜 !', 'data' => array());
  80. $json['data']['type'] = $text_worker->user_data[$my_uid]['type'];
  81. $text_worker->uidConnections[$my_uid]['cons']->send(json_encode($json));
  82. $text_worker->uidConnections[$your_uid]['cons']->send(json_encode($json));
  83. }
  84. }
  85. }
  86. }
  87. }
  88. // 当客户端断开时,广播给所有客户端
  89. function handle_close($connection)
  90. {
  91. global $text_worker;
  92. /*foreach ($text_worker->connections as $conn) {
  93. $conn->send("user[{$connection->uid}] logout");
  94. }*/
  95. }
  96. /**
  97. * 判断输赢
  98. * $qipan 棋盘数据
  99. * $i 下子时的横坐标
  100. * $i 下子时的纵坐标
  101. * $type 1黑方 2红方
  102. * $global_i 棋盘边界值
  103. * $global_j 棋盘边界值
  104. */
  105. function get_who_win($qipan = array(), $i = -1, $j = -1, $type = 0, $global_i = 0, $global_j = 0)
  106. {
  107. $count = 0;
  108. $temp_type = $type;
  109. if (empty($qipan) || $i < 0 || $j < 0 || $type <= 0) {
  110. return $count;
  111. }
  112. echo json_encode($qipan) . "\n";
  113. echo 'i=' . $i . '|j=' . $j . '|type=' . $type . '|gi=' . $global_i . '|gj=' . $global_j . "\n";
  114. /*左右上下的判断*/
  115. $count = 1;
  116. $a = array(
  117. 0 => array('index' => $j, 'border' => $global_j), //左右,
  118. 1 => array('index' => $i, 'border' => $global_i) //上下
  119. );
  120. for ($round = 0; $round <= 1; $round++) {
  121. $mov1_num = 1;
  122. $mov2_num = 1;
  123. while (true) {
  124. $mov1 = $a[$round]['index'] + $mov1_num;
  125. $mov2 = $a[$round]['index'] - $mov2_num;
  126. $temp_mov1 = $temp_mov2 = -1;
  127. if ($mov1_num > 0) {
  128. if ($round == 0 && $mov1 <= $global_j) {
  129. $temp_mov1 = $qipan[$i][$mov1];
  130. var_dump($i . ',' . $mov1 . ',' . $temp_mov1);
  131. } elseif ($round == 1 && $mov1 <= $global_i) {
  132. $temp_mov1 = $qipan[$mov1][$j];
  133. }
  134. if ($temp_mov1 == $temp_type) {
  135. $count++;
  136. var_dump('count=' . $count);
  137. $mov1_num++;
  138. } else {
  139. $mov1_num = 0;
  140. }
  141. } else {
  142. $mov1_num = 0;
  143. }
  144. if ($mov2 >= 0 && $mov2_num > 0) {
  145. if ($round == 0) {
  146. $temp_mov2 = $qipan[$i][$mov2];
  147. var_dump($i . ',' . $mov2 . ',' . $temp_mov1);
  148. } elseif ($round == 1) {
  149. $temp_mov2 = $qipan[$mov2][$j];
  150. }
  151. if ($temp_mov2 == $temp_type) {
  152. $count++;
  153. $mov2_num++;
  154. } else {
  155. $mov2_num = 0;
  156. }
  157. } else {
  158. $mov2_num = 0;
  159. }
  160. if ($count >= 5) {
  161. return $count;
  162. }
  163. if (($mov1_num == 0 && $mov2_num == 0)) {
  164. break;
  165. }
  166. }
  167. }
  168. /*斜角的判断*/
  169. $count = 1;
  170. for ($round = 0; $round <= 1; $round++) {
  171. $mov1_num = 1;
  172. $mov2_num = 1;
  173. while (true) {
  174. $temp_mov1 = $temp_mov2 = -1;
  175. if (($i - $mov1_num) >= 0 && ($j - $mov1_num) >= 0 && ($j + $mov1_num) <= $global_j && $mov1_num > 0) {
  176. if ($round == 0) {
  177. $temp_mov1 = $qipan[$i - $mov1_num][$j + $mov1_num];
  178. } elseif ($round == 1) {
  179. $temp_mov1 = $qipan[$i - $mov1_num][$j - $mov1_num];
  180. }
  181. if ($temp_mov1 == $temp_type) {
  182. $count++;
  183. $mov1_num++;
  184. } else {
  185. $mov1_num = 0;
  186. }
  187. } else {
  188. $mov1_num = 0;
  189. }
  190. if (($i + $mov2_num) <= $global_i && ($j - $mov2_num) >= 0 && ($j + $mov2_num) <= $global_j && $mov2_num > 0) {
  191. if ($round == 0) {
  192. $temp_mov2 = $qipan[$i + $mov2_num][$j - $mov2_num];
  193. } elseif ($round == 1) {
  194. $temp_mov2 = $qipan[$i + $mov2_num][$j + $mov2_num];
  195. }
  196. if ($temp_mov2 == $temp_type) {
  197. $count++;
  198. $mov2_num++;
  199. } else {
  200. $mov2_num = 0;
  201. }
  202. } else {
  203. $mov2_num = 0;
  204. }
  205. if ($count >= 5) {
  206. return $count;
  207. }
  208. if (($mov1_num == 0 && $mov2_num == 0)) {
  209. break;
  210. }
  211. }
  212. }
  213. return $count;
  214. }
  215. // 创建一个文本协议的Worker监听2347接口
  216. $text_worker = new Worker("websocket://0.0.0.0:2347");
  217. // 只启动1个进程
  218. $text_worker->count = 1;
  219. $text_worker->uidConnections = array();
  220. $text_worker->user_data = array();
  221. $text_worker->onConnect = 'handle_connection';
  222. $text_worker->onMessage = 'handle_message';
  223. $text_worker->onClose = 'handle_close';
  224. Worker::runAll();

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  9. <style type="text/css">
  10. td{
  11. width:30px;
  12. height:30px;
  13. border:1px solid #666;
  14. }
  15. table{
  16. border-collapse: collapse;
  17. border-spacing: 0;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <div class="player"></div>
  23. <div id="demo"></div>
  24. </body>
  25. </html>
  26. <script>
  27. table = "<table>";
  28. for (let i = 0; i <= 15; i++) {
  29. table += "<tr>";
  30. for (let j = 0; j <= 15; j++) {
  31. table += "<td onclick='press_on(this)' id='div_" + i + "_" + j + "'>" + "</td>";
  32. }
  33. table += "</tr>";
  34. }
  35. table += "</table>";
  36. $('#demo').html(table);
  37. ws = new WebSocket("ws://127.0.0.1:2347");
  38. ws.onopen = function () {
  39. console.log("连接成功");
  40. };
  41. ws.onmessage = function (e) {
  42. //alert("收到服务端的消息:" + e.data);
  43. console.log(e.data);
  44. var jsonobj = eval('(' + e.data + ')');
  45. if (jsonobj.status == 1 && jsonobj.data.name != null) {//初始化名字
  46. alert(jsonobj.data.name);
  47. $('.player').html(jsonobj.data.name);
  48. }
  49. if (jsonobj.status == 2) {//
  50. var type = jsonobj.data.type;
  51. var press_i = jsonobj.data.press_i;
  52. var press_j = jsonobj.data.press_j;
  53. id = '#div_' + press_i + '_' + press_j;
  54. $(id).unbind("click");
  55. if (type == 1) {
  56. $(id).html("<div style='background:#000000;width:30px;height:30px;border-radius:50%;'></div>");
  57. }
  58. if (type == 2) {
  59. $(id).html("<div style='background:#ffbc00;width:30px;height:30px;border-radius:50%;'></div>");
  60. }
  61. }
  62. if (jsonobj.status == 3) {//
  63. var msg = jsonobj.msg;
  64. var r = confirm(msg + ',是否从新开始?');
  65. if (r) {
  66. window.location.reload(true);
  67. return;
  68. } else {
  69. return;
  70. }
  71. }
  72. };
  73. function press_on(value) {
  74. var send = '{"status":2,"data":"' + value.id + '"}';
  75. console.log(send);
  76. ws.send(send);
  77. }
  78. </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. Educational Codeforces Round 106 (Rated for Div. 2) 简单题解(A~C)

    1499A. Domino on Windowsill 题意:给定一个 \(2 \times n\) 的空间,\(k1.k2 行要设置为白色(2 \times 1)\) 然后其他的设置为黑色 思路:为 ...

  2. 第六届蓝桥杯(2015)C/C++大学A组省赛题解

    第一题.方程整数解 答案:10 18 24,最小的为 10 int main() { ios_base::sync_with_stdio(false), cin.tie(0); for (int i ...

  3. 概率图模型 · 蒙特卡洛采样 · MCMC | 非常好的教学视频

    https://www.bilibili.com/video/BV17D4y1o7J2?p=1 非常感谢!感觉学会一点了,应该能写作业了

  4. linux 命令使用总结:vim,nohup,find,df,du,sudo,netstat,ll,curl,lastlog

    1.Vim命令使用 vim 为编辑文本命令: vim 文件  回车即可查看文件 按 字母 i 键,即可进入 insert 编辑模式. 按 ESC 键即可退出编辑模式 输入冒号:wq 即可保存修改 输入 ...

  5. Shell-流程控制-if-then-elif

  6. [官网]微软服务器TLS的支持情况

    https://learn.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp-#tls-pro ...

  7. [转帖]清除掉shared pool中某条sql语句方法

    https://www.xifenfei.com/2012/02/%E6%B8%85%E9%99%A4%E6%8E%89shared-pool%E4%B8%AD%E6%9F%90%E6%9D%A1sq ...

  8. ingress nginx 支持的K8S版本以及nginx版本信息

  9. [转帖]Jmeter学习笔记(八)——监听器元件之聚合报告

    https://www.cnblogs.com/pachongshangdexuebi/p/11507298.html 1.聚合报告添加 聚合报告是常用的监听器之一,添加路径: 点击线程组->添 ...

  10. [转帖]linux内存挂载

    1.主要功能 在linux中,为了提高读写速度,可以将内存挂载到目录,常见的文件格式有tmpfs和ramfs. 2.挂载步骤 $ sudo mkdir /mnt/tmp $ sudo mkdir /m ...