1. #include <X11/Xlib.h>
  2. #include <stdlib.h>
  3. #include <X11/keysym.h>
  4. #include <cstring>
  5. #include <iostream>
  6. using namespace std;
  7. enum CELL_STATE { CELL_EMPTY, CELL_O, CELL_X };
  8. enum GAME_STATE { X_TURN, O_TURN, X_WON, O_WON, DRAW };
  9.  
  10. class Game {
  11. public:
  12. Game();
  13.  
  14. CELL_STATE getCellState(int x, int y);
  15. GAME_STATE getGameState();
  16.  
  17. bool makeMove(int x, int y);
  18. bool makeRandomMove();
  19. void restart();
  20. private:
  21. CELL_STATE _boardState[3][3];
  22. GAME_STATE _gameState;
  23. int _turnsPassed;
  24.  
  25. void _checkForEnd();
  26. };
  27.  
  28. inline CELL_STATE Game::getCellState(int x, int y) {
  29. return _boardState[x][y];
  30. }
  31.  
  32. inline GAME_STATE Game::getGameState() {
  33. return _gameState;
  34. }
  35.  
  36. Game::Game() {
  37. restart();
  38. }
  39.  
  40. void Game::restart() {
  41. for(int i = 0; i < 3; i++) {
  42. for(int j = 0; j < 3; j++) {
  43. _boardState[i][j] = CELL_EMPTY;
  44. }
  45. }
  46. _gameState = X_TURN;
  47. _turnsPassed = 0;
  48. }
  49.  
  50. bool Game::makeMove(int x, int y) {
  51. GAME_STATE nextState;
  52. CELL_STATE curPlayerCell;
  53.  
  54. if(_gameState == O_TURN) {
  55. curPlayerCell = CELL_O;
  56. nextState = X_TURN;
  57. } else if(_gameState == X_TURN) {
  58. curPlayerCell = CELL_X;
  59. nextState = O_TURN;
  60. } else {
  61. return false;
  62. }
  63.  
  64. if(_boardState[x][y] != CELL_EMPTY) {
  65. return false;
  66. }
  67.  
  68. _boardState[x][y] = curPlayerCell;
  69. _turnsPassed++;
  70. _gameState = nextState;
  71.  
  72. _checkForEnd();
  73. return true;
  74. }
  75.  
  76. bool Game::makeRandomMove() {
  77. GAME_STATE nextState;
  78. CELL_STATE curPlayerCell;
  79.  
  80. if(_gameState == O_TURN) {
  81. curPlayerCell = CELL_O;
  82. nextState = X_TURN;
  83. } else if(_gameState == X_TURN) {
  84. curPlayerCell = CELL_X;
  85. nextState = O_TURN;
  86. } else {
  87. return false;
  88. }
  89.  
  90. int nFreeCells = 0;
  91. int freeCells[9][2];
  92. for(int i = 0; i < 3; i++) {
  93. for(int j = 0; j < 3; j++) {
  94. if(_boardState[i][j] == CELL_EMPTY) {
  95. freeCells[nFreeCells][0] = i;
  96. freeCells[nFreeCells][1] = j;
  97. nFreeCells++;
  98. }
  99. }
  100. }
  101.  
  102. if(nFreeCells == 0) {
  103. return false;
  104. }
  105.  
  106. int choice = rand() % nFreeCells;
  107. int x = freeCells[choice][0];
  108. int y = freeCells[choice][1];
  109.  
  110. _boardState[x][y] = curPlayerCell;
  111. _turnsPassed++;
  112. _gameState = nextState;
  113.  
  114. _checkForEnd();
  115. return true;
  116. }
  117.  
  118. void Game::_checkForEnd() {
  119. if(_turnsPassed == 9) {
  120. _gameState = DRAW;
  121. }
  122.  
  123. CELL_STATE winningCell = CELL_EMPTY;
  124.  
  125. for(int i = 0; i < 3; i++) {
  126. if((_boardState[i][0] == _boardState[i][1]) &&
  127. (_boardState[i][1] == _boardState[i][2]) &&
  128. (_boardState[i][0] != CELL_EMPTY)) {
  129. winningCell = _boardState[i][0];
  130. }
  131. }
  132. for(int i = 0; i < 3; i++) {
  133. if((_boardState[0][i] == _boardState[1][i]) &&
  134. (_boardState[1][i] == _boardState[2][i]) &&
  135. (_boardState[0][1] != CELL_EMPTY)) {
  136. winningCell = _boardState[0][i];
  137. }
  138. }
  139. if((_boardState[0][0] == _boardState[1][1]) &&
  140. (_boardState[1][1] == _boardState[2][2]) &&
  141. (_boardState[0][0] != CELL_EMPTY)) {
  142. winningCell = _boardState[0][0];
  143. }
  144. if((_boardState[2][0] == _boardState[1][1]) &&
  145. (_boardState[1][1] == _boardState[0][2]) &&
  146. (_boardState[2][0] != CELL_EMPTY)) {
  147. winningCell = _boardState[2][0];
  148. }
  149.  
  150. if(winningCell == CELL_X) {
  151. _gameState = X_WON;
  152. } else if(winningCell == CELL_O) {
  153. _gameState = O_WON;
  154. }
  155. }
  156.  
  157. class HelloWorld {
  158. public:
  159. HelloWorld(Display* display);
  160.  
  161. Window getWindow();
  162.  
  163. void draw();
  164. void map();
  165.  
  166. void handleKeyPress(const XKeyEvent& event);
  167. void handleMousePress(const XButtonEvent& event);
  168. void restartGame();
  169. private:
  170. const static int MIN_CELL_SIZE;
  171. const static int STRING_HEIGHT;
  172. const static char WINDOW_FONT[];
  173.  
  174. Display* _display;
  175. Screen* _screen;
  176. Window _window;
  177.  
  178. Font _font;
  179. unsigned long _blackColor;
  180. unsigned long _whiteColor;
  181.  
  182. Game _game;
  183.  
  184. void _drawO(const GC& gc, int x, int y, int w, int h);
  185. void _drawX(const GC& gc, int x, int y, int w, int h);
  186.  
  187. void _drawString(const GC& gc, const char* str, int x, int y);
  188. void _drawStringCentered(const GC& gc, const char* str, int x, int y, int w, int h);
  189. };
  190.  
  191. inline Window HelloWorld::getWindow() {
  192. return _window;
  193. }
  194.  
  195. const int HelloWorld::MIN_CELL_SIZE = 50;
  196. const int HelloWorld::STRING_HEIGHT = 20;
  197. const char HelloWorld::WINDOW_FONT[] = "-*-*-*-*-*-*-12-*-*-*-*-*-*-*";
  198.  
  199. HelloWorld::HelloWorld(Display* display) :
  200. _game() {
  201.  
  202. _display = display;
  203. _screen = XDefaultScreenOfDisplay(display);
  204.  
  205. _blackColor = BlackPixelOfScreen(_screen);
  206. _whiteColor = WhitePixelOfScreen(_screen);
  207. _font = XLoadFont(_display, WINDOW_FONT);
  208.  
  209. int screenWidth = XWidthOfScreen(_screen);
  210. int screenHeight = XHeightOfScreen(_screen);
  211.  
  212. int windowWidth = MIN_CELL_SIZE * 3;
  213. int windowHeight = MIN_CELL_SIZE * 3 + STRING_HEIGHT * 3;
  214. int windowX = (screenWidth + windowWidth) / 2;
  215. int windowY = (screenHeight + windowHeight) / 2;
  216. _window = XCreateSimpleWindow(_display, XRootWindowOfScreen(_screen),
  217. windowX, windowY, windowWidth, windowHeight, 1, _blackColor,
  218. _whiteColor);
  219.  
  220. long eventMask = ButtonPressMask | ExposureMask | KeyPressMask;
  221. XSelectInput(_display, _window, eventMask);
  222.  
  223. draw();
  224. }
  225.  
  226. void HelloWorld::draw() {
  227. // Getting window dimensions.
  228. Window rootWindow;
  229. int x, y;
  230. unsigned int width, height, borderWidth, bitDepth;
  231. XGetGeometry(_display, _window, &rootWindow, &x, &y, &width, &height,
  232. &borderWidth, &bitDepth);
  233.  
  234. // Setting up the GC.
  235. GC gc = XDefaultGCOfScreen(_screen);
  236. XSetBackground(_display, gc, _whiteColor);
  237. XSetFont(_display, gc, _font);
  238. XSetForeground(_display, gc, _blackColor);
  239.  
  240. // Clearing the window.
  241. XClearArea(_display, _window, 0, 0, width, height, false);
  242.  
  243. // Is the window large enough for us?
  244. if((width < MIN_CELL_SIZE * 3) ||
  245. (height < (MIN_CELL_SIZE * 3 + STRING_HEIGHT * 3))) {
  246. _drawStringCentered(gc, "Window too small.", 0, 0, width, height);
  247. return;
  248. }
  249.  
  250. // Calculating grid cell sizes.
  251. int xStepSize = width / 3;
  252. int yStepSize = (height - STRING_HEIGHT * 3) / 3;
  253.  
  254. // Drawing glyphs.
  255. for(int i = 0; i < 3; i++) {
  256. for(int j = 0; j < 3; j++) {
  257. switch(_game.getCellState(i, j)) {
  258. case CELL_O:
  259. _drawO(gc, xStepSize * i, STRING_HEIGHT * 2 + yStepSize * j,
  260. xStepSize, yStepSize);
  261. break;
  262. case CELL_X:
  263. _drawX(gc, xStepSize * i, STRING_HEIGHT * 2 + yStepSize * j,
  264. xStepSize, yStepSize);
  265. break;
  266. default:
  267. break;
  268. }
  269. }
  270. }
  271. XSetBackground(_display, gc, _whiteColor);
  272. XSetForeground(_display, gc, _blackColor);
  273.  
  274. // Drawing the grid lines.
  275. for(int i = 0; i <= 3; i++) {
  276. int yValue = STRING_HEIGHT * 2 + yStepSize * i;
  277. XDrawLine(_display, _window, gc, 0, yValue, width, yValue);
  278. }
  279. for(int i = 1; i <= 2; i++) {
  280. int xValue = xStepSize * i;
  281. XDrawLine(_display, _window, gc, xValue, STRING_HEIGHT * 2, xValue,
  282. height - STRING_HEIGHT);
  283. }
  284.  
  285. // Drawing the strings.
  286. _drawStringCentered(gc, "Hello, World!", 0, 0, width, STRING_HEIGHT);
  287. _drawStringCentered(gc, "[R]estart", 0, height - STRING_HEIGHT,
  288. width, STRING_HEIGHT);
  289.  
  290. switch(_game.getGameState()) {
  291. case X_TURN:
  292. _drawStringCentered(gc, "It is your turn to play.", 0, STRING_HEIGHT,
  293. width, STRING_HEIGHT);
  294. break;
  295. case O_TURN:
  296. _drawStringCentered(gc, "Please wait, thinking...", 0, STRING_HEIGHT,
  297. width, STRING_HEIGHT);
  298. break;
  299. case X_WON:
  300. _drawStringCentered(gc, "You have won.", 0, STRING_HEIGHT, width,
  301. STRING_HEIGHT);
  302. break;
  303. case O_WON:
  304. _drawStringCentered(gc, "You have lost.", 0, STRING_HEIGHT, width,
  305. STRING_HEIGHT);
  306. break;
  307. case DRAW:
  308. _drawStringCentered(gc, "It is a draw.", 0, STRING_HEIGHT, width,
  309. STRING_HEIGHT);
  310. break;
  311. default:
  312. break;
  313. }
  314. }
  315.  
  316. void HelloWorld::map() {
  317. XMapWindow(_display, _window);
  318. }
  319.  
  320. void HelloWorld::handleKeyPress(const XKeyEvent& event) {
  321. unsigned int keyCode_r = XKeysymToKeycode(_display, XK_r);
  322. unsigned int keyCode_q = XKeysymToKeycode(_display, XK_q);
  323.  
  324. if(event.keycode == keyCode_r) {
  325. _game.restart();
  326. draw();
  327. } else if(event.keycode == keyCode_q) {
  328. // Quit, somehow
  329. }
  330. }
  331.  
  332. void HelloWorld::handleMousePress(const XButtonEvent& event) {
  333. if(event.button == 1) {
  334. Window rootWindow;
  335. int winX, winY;
  336. unsigned int width, height, borderWidth, bitDepth;
  337. XGetGeometry(_display, _window, &rootWindow, &winX, &winY, &width,
  338. &height, &borderWidth, &bitDepth);
  339.  
  340. if((event.y >= 2 * STRING_HEIGHT) &&
  341. (event.y < (height - STRING_HEIGHT))) {
  342. int xStepSize = width / 3;
  343. int yStepSize = (height - STRING_HEIGHT * 3) / 3;
  344.  
  345. int cellX = event.x / xStepSize;
  346. int cellY = (event.y - STRING_HEIGHT * 2) / yStepSize;
  347.  
  348. if(_game.makeMove(cellX, cellY)) {
  349. if(_game.getGameState() == O_TURN) {
  350. _game.makeRandomMove();
  351. }
  352. draw();
  353. }
  354. }
  355. }
  356. }
  357.  
  358. void HelloWorld::restartGame() {
  359. _game.restart();
  360. draw();
  361. }
  362.  
  363. void HelloWorld::_drawO(const GC& gc, int x, int y, int w, int h) {
  364. XSetBackground(_display, gc, _whiteColor);
  365. XSetForeground(_display, gc, _blackColor);
  366. XFillArc(_display, _window, gc, x + w/10, y + h/10, (w*4)/5, (h*4)/5, 0,
  367. 360*64);
  368.  
  369. XSetForeground(_display, gc, _whiteColor);
  370. XFillArc(_display, _window, gc, x + w/5, y + h/5, (w*3)/5, (h*3)/5, 0,
  371. 360*64);
  372. }
  373.  
  374. void HelloWorld::_drawX(const GC& gc, int x, int y, int w, int h) {
  375. static const int POINT_COUNT = 12;
  376. static const XPoint RAW_CROSS[] = { {1, 2}, {2, 1}, {5, 4}, {8, 1}, {9, 2},
  377. {6, 5}, {9, 8}, {8, 9}, {5, 6}, {2, 9}, {1, 8}, {4, 5} };
  378.  
  379. XPoint scaledCross[POINT_COUNT];
  380. for(int i = 0; i < POINT_COUNT; i++) {
  381. scaledCross[i].x = (RAW_CROSS[i].x * w) / 10 + x;
  382. scaledCross[i].y = (RAW_CROSS[i].y * h) / 10 + y;
  383. }
  384.  
  385. XSetBackground(_display, gc, _whiteColor);
  386. XSetForeground(_display, gc, _blackColor);
  387. XFillPolygon(_display, _window, gc, scaledCross, POINT_COUNT, Nonconvex,
  388. CoordModeOrigin);
  389. }
  390.  
  391. void HelloWorld::_drawString(const GC& gc, const char* str, int x, int y) {
  392. XDrawString(_display, _window, gc, x, y, str, strlen(str));
  393. }
  394.  
  395. void HelloWorld::_drawStringCentered(const GC& gc, const char* str, int x, int y,
  396. int w, int h) {
  397. int direction, ascent, descent;
  398. XCharStruct strDimensions;
  399. XTextExtents(XQueryFont(_display, XGContextFromGC(gc)), str, strlen(str),
  400. &direction, &ascent, &descent, &strDimensions);
  401.  
  402. int newX = x + (w - strDimensions.width) / 2;
  403. int newY = y + (h + strDimensions.ascent - strDimensions.descent) / 2;
  404. _drawString(gc, str, newX, newY);
  405. }
  406.  
  407. int main() {
  408. Display* display = XOpenDisplay(NULL);
  409. if(!display) {
  410. cerr << "Unable to connect to X server." << endl;
  411. exit(1);
  412. }
  413.  
  414. HelloWorld mainWindow(display);
  415. mainWindow.map();
  416.  
  417. XFlush(display);
  418.  
  419. XEvent event;
  420. while(true) {
  421. XNextEvent(display, &event);
  422.  
  423. switch(event.type) {
  424. case ButtonPress:
  425. mainWindow.handleMousePress((XButtonEvent)event.xbutton);
  426. case Expose:
  427. if(event.xexpose.count == 0) {
  428. mainWindow.draw();
  429. }
  430. break;
  431. case KeyPress:
  432. mainWindow.handleKeyPress((XKeyEvent)event.xkey);
  433. default:
  434. break;
  435. }
  436. }
  437.  
  438. XCloseDisplay(display);
  439. return 0;
  440. }

X11 五子棋的更多相关文章

  1. html+js+node实现五子棋线上对战,五子棋最简易算法

    首先附上我的github地址,https://github.com/jiangzhenfei/five,线上实例:http://47.93.103.19:5900/client/ 线上实例,你可以随意 ...

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

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

  3. java swing 双人五子棋源代码

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; impo ...

  4. HTML5 五子棋 - JS/Canvas 游戏

    背景介绍 因为之前用c#的winform中的gdi+,java图形包做过五子棋,所以做这个逻辑思路也就驾轻就熟,然而最近想温故html5的canvas绘图功能(公司一般不用这些),所以做了个五子棋,当 ...

  5. 阿里云ECS(Centos)开启X11的步骤

    阿里云ECS(Centos)开启X11的步骤 1.修改sshd_config X11Forwarding yes 2.yum -y install xorg-x11-xauth xorg-x11-ut ...

  6. [收藏]C++简单五子棋

    #include<iostream> #include<iomanip> using namespace std; ; //棋盘行数 ; //棋盘列数 char p[X][Y] ...

  7. jQuery网页版五子棋小游戏源码下载

    体验效果:http://hovertree.com/texiao/game/4/ 网页五子棋源代码: <!DOCTYPE html> <html> <head> & ...

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

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

  9. jquery在线五子棋

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

随机推荐

  1. 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展

    [Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...

  2. 修改List报ConcurrentModificationException异常原因分析

    使用迭代器遍历List的时候修改List报ConcurrentModificationException异常原因分析 在使用Iterator来迭代遍历List的时候如果修改该List对象,则会报jav ...

  3. C#中 如何执行带GO的sql 语句

    C#中是不允许执行带GO的sql 语句的, 如何做呢? 思路就是将带GO的sql语句转化为分段执行, 但在同一事务内执行. 扩展方法是个很不错的主意, 但是尽量不要影响原来的cmd的一些东东, 如 c ...

  4. 弃用个人博客站重返CSDN缘由

    最近悄然关闭了自己的个人博客小站,重新返回了CSDN写博客.恰逢周末,闲暇尚有,敲击键盘记录一下. 其实最初关闭个人基于SAE的个人博客站是一周前开始的,想想自己的博客已经有两周年多的时间了,刚刚创建 ...

  5. [APUE]进程控制(中)

    一.wait和waitpid函数 当一个进程正常或异常终止时会向父进程发送SIGCHLD信号.对于这种信号系统默认会忽略.调用wait/waidpid的进程可能会: 阻塞(如果其子进程都还在运行); ...

  6. 基于session 的springMvc 国际化

    项目中采用springMvc的框架,需要动态切换语言,找了一些资料,最后决定采用基于session的动态切换,实现动态切换中文,英文,韩文,其实就是把中文翻译成其他语言显示 springMvc国际化包 ...

  7. RabbitMQ Exchange类型详解

    前言 在上一篇文章中,我们知道了RabbitMQ的消息流程如下: 但在具体的使用中,我们还需知道exchange的类型,因为不同的类型对应不同的队列和路由规则. 在rabbitmq中,exchange ...

  8. Spring实战——XML和JavaConfig的混合配置

    前言 看了园龄已经两年多了,再不能写完内容直接点击发布,留下一片密密麻麻的文字让别人看的头昏脑涨.所以现在每次写完主要内容后,还需要对于格式稍稍调整下.那么有没有什么编辑模式能够在你写完文章后基本也把 ...

  9. .net 实战 根据configuration选项生成不同的config文件

    项目开发过程中都会遇到的问题,开发环境的配置肯定是和生产环境不一样的,一直都是重复手动拷贝,但是配置太多拷贝的弊端就显现出来了,为了解决这个问题可以有几种方案: 1.Web.config Transf ...

  10. Python自动化开发-变量、数据类型和运算

    一.变量 变量定义:Variables are used to store infomation to referrenced and manipulated in a computer progra ...