X11 五子棋
- #include <X11/Xlib.h>
- #include <stdlib.h>
- #include <X11/keysym.h>
- #include <cstring>
- #include <iostream>
- using namespace std;
- enum CELL_STATE { CELL_EMPTY, CELL_O, CELL_X };
- enum GAME_STATE { X_TURN, O_TURN, X_WON, O_WON, DRAW };
- class Game {
- public:
- Game();
- CELL_STATE getCellState(int x, int y);
- GAME_STATE getGameState();
- bool makeMove(int x, int y);
- bool makeRandomMove();
- void restart();
- private:
- CELL_STATE _boardState[3][3];
- GAME_STATE _gameState;
- int _turnsPassed;
- void _checkForEnd();
- };
- inline CELL_STATE Game::getCellState(int x, int y) {
- return _boardState[x][y];
- }
- inline GAME_STATE Game::getGameState() {
- return _gameState;
- }
- Game::Game() {
- restart();
- }
- void Game::restart() {
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- _boardState[i][j] = CELL_EMPTY;
- }
- }
- _gameState = X_TURN;
- _turnsPassed = 0;
- }
- bool Game::makeMove(int x, int y) {
- GAME_STATE nextState;
- CELL_STATE curPlayerCell;
- if(_gameState == O_TURN) {
- curPlayerCell = CELL_O;
- nextState = X_TURN;
- } else if(_gameState == X_TURN) {
- curPlayerCell = CELL_X;
- nextState = O_TURN;
- } else {
- return false;
- }
- if(_boardState[x][y] != CELL_EMPTY) {
- return false;
- }
- _boardState[x][y] = curPlayerCell;
- _turnsPassed++;
- _gameState = nextState;
- _checkForEnd();
- return true;
- }
- bool Game::makeRandomMove() {
- GAME_STATE nextState;
- CELL_STATE curPlayerCell;
- if(_gameState == O_TURN) {
- curPlayerCell = CELL_O;
- nextState = X_TURN;
- } else if(_gameState == X_TURN) {
- curPlayerCell = CELL_X;
- nextState = O_TURN;
- } else {
- return false;
- }
- int nFreeCells = 0;
- int freeCells[9][2];
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- if(_boardState[i][j] == CELL_EMPTY) {
- freeCells[nFreeCells][0] = i;
- freeCells[nFreeCells][1] = j;
- nFreeCells++;
- }
- }
- }
- if(nFreeCells == 0) {
- return false;
- }
- int choice = rand() % nFreeCells;
- int x = freeCells[choice][0];
- int y = freeCells[choice][1];
- _boardState[x][y] = curPlayerCell;
- _turnsPassed++;
- _gameState = nextState;
- _checkForEnd();
- return true;
- }
- void Game::_checkForEnd() {
- if(_turnsPassed == 9) {
- _gameState = DRAW;
- }
- CELL_STATE winningCell = CELL_EMPTY;
- for(int i = 0; i < 3; i++) {
- if((_boardState[i][0] == _boardState[i][1]) &&
- (_boardState[i][1] == _boardState[i][2]) &&
- (_boardState[i][0] != CELL_EMPTY)) {
- winningCell = _boardState[i][0];
- }
- }
- for(int i = 0; i < 3; i++) {
- if((_boardState[0][i] == _boardState[1][i]) &&
- (_boardState[1][i] == _boardState[2][i]) &&
- (_boardState[0][1] != CELL_EMPTY)) {
- winningCell = _boardState[0][i];
- }
- }
- if((_boardState[0][0] == _boardState[1][1]) &&
- (_boardState[1][1] == _boardState[2][2]) &&
- (_boardState[0][0] != CELL_EMPTY)) {
- winningCell = _boardState[0][0];
- }
- if((_boardState[2][0] == _boardState[1][1]) &&
- (_boardState[1][1] == _boardState[0][2]) &&
- (_boardState[2][0] != CELL_EMPTY)) {
- winningCell = _boardState[2][0];
- }
- if(winningCell == CELL_X) {
- _gameState = X_WON;
- } else if(winningCell == CELL_O) {
- _gameState = O_WON;
- }
- }
- class HelloWorld {
- public:
- HelloWorld(Display* display);
- Window getWindow();
- void draw();
- void map();
- void handleKeyPress(const XKeyEvent& event);
- void handleMousePress(const XButtonEvent& event);
- void restartGame();
- private:
- const static int MIN_CELL_SIZE;
- const static int STRING_HEIGHT;
- const static char WINDOW_FONT[];
- Display* _display;
- Screen* _screen;
- Window _window;
- Font _font;
- unsigned long _blackColor;
- unsigned long _whiteColor;
- Game _game;
- void _drawO(const GC& gc, int x, int y, int w, int h);
- void _drawX(const GC& gc, int x, int y, int w, int h);
- void _drawString(const GC& gc, const char* str, int x, int y);
- void _drawStringCentered(const GC& gc, const char* str, int x, int y, int w, int h);
- };
- inline Window HelloWorld::getWindow() {
- return _window;
- }
- const int HelloWorld::MIN_CELL_SIZE = 50;
- const int HelloWorld::STRING_HEIGHT = 20;
- const char HelloWorld::WINDOW_FONT[] = "-*-*-*-*-*-*-12-*-*-*-*-*-*-*";
- HelloWorld::HelloWorld(Display* display) :
- _game() {
- _display = display;
- _screen = XDefaultScreenOfDisplay(display);
- _blackColor = BlackPixelOfScreen(_screen);
- _whiteColor = WhitePixelOfScreen(_screen);
- _font = XLoadFont(_display, WINDOW_FONT);
- int screenWidth = XWidthOfScreen(_screen);
- int screenHeight = XHeightOfScreen(_screen);
- int windowWidth = MIN_CELL_SIZE * 3;
- int windowHeight = MIN_CELL_SIZE * 3 + STRING_HEIGHT * 3;
- int windowX = (screenWidth + windowWidth) / 2;
- int windowY = (screenHeight + windowHeight) / 2;
- _window = XCreateSimpleWindow(_display, XRootWindowOfScreen(_screen),
- windowX, windowY, windowWidth, windowHeight, 1, _blackColor,
- _whiteColor);
- long eventMask = ButtonPressMask | ExposureMask | KeyPressMask;
- XSelectInput(_display, _window, eventMask);
- draw();
- }
- void HelloWorld::draw() {
- // Getting window dimensions.
- Window rootWindow;
- int x, y;
- unsigned int width, height, borderWidth, bitDepth;
- XGetGeometry(_display, _window, &rootWindow, &x, &y, &width, &height,
- &borderWidth, &bitDepth);
- // Setting up the GC.
- GC gc = XDefaultGCOfScreen(_screen);
- XSetBackground(_display, gc, _whiteColor);
- XSetFont(_display, gc, _font);
- XSetForeground(_display, gc, _blackColor);
- // Clearing the window.
- XClearArea(_display, _window, 0, 0, width, height, false);
- // Is the window large enough for us?
- if((width < MIN_CELL_SIZE * 3) ||
- (height < (MIN_CELL_SIZE * 3 + STRING_HEIGHT * 3))) {
- _drawStringCentered(gc, "Window too small.", 0, 0, width, height);
- return;
- }
- // Calculating grid cell sizes.
- int xStepSize = width / 3;
- int yStepSize = (height - STRING_HEIGHT * 3) / 3;
- // Drawing glyphs.
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- switch(_game.getCellState(i, j)) {
- case CELL_O:
- _drawO(gc, xStepSize * i, STRING_HEIGHT * 2 + yStepSize * j,
- xStepSize, yStepSize);
- break;
- case CELL_X:
- _drawX(gc, xStepSize * i, STRING_HEIGHT * 2 + yStepSize * j,
- xStepSize, yStepSize);
- break;
- default:
- break;
- }
- }
- }
- XSetBackground(_display, gc, _whiteColor);
- XSetForeground(_display, gc, _blackColor);
- // Drawing the grid lines.
- for(int i = 0; i <= 3; i++) {
- int yValue = STRING_HEIGHT * 2 + yStepSize * i;
- XDrawLine(_display, _window, gc, 0, yValue, width, yValue);
- }
- for(int i = 1; i <= 2; i++) {
- int xValue = xStepSize * i;
- XDrawLine(_display, _window, gc, xValue, STRING_HEIGHT * 2, xValue,
- height - STRING_HEIGHT);
- }
- // Drawing the strings.
- _drawStringCentered(gc, "Hello, World!", 0, 0, width, STRING_HEIGHT);
- _drawStringCentered(gc, "[R]estart", 0, height - STRING_HEIGHT,
- width, STRING_HEIGHT);
- switch(_game.getGameState()) {
- case X_TURN:
- _drawStringCentered(gc, "It is your turn to play.", 0, STRING_HEIGHT,
- width, STRING_HEIGHT);
- break;
- case O_TURN:
- _drawStringCentered(gc, "Please wait, thinking...", 0, STRING_HEIGHT,
- width, STRING_HEIGHT);
- break;
- case X_WON:
- _drawStringCentered(gc, "You have won.", 0, STRING_HEIGHT, width,
- STRING_HEIGHT);
- break;
- case O_WON:
- _drawStringCentered(gc, "You have lost.", 0, STRING_HEIGHT, width,
- STRING_HEIGHT);
- break;
- case DRAW:
- _drawStringCentered(gc, "It is a draw.", 0, STRING_HEIGHT, width,
- STRING_HEIGHT);
- break;
- default:
- break;
- }
- }
- void HelloWorld::map() {
- XMapWindow(_display, _window);
- }
- void HelloWorld::handleKeyPress(const XKeyEvent& event) {
- unsigned int keyCode_r = XKeysymToKeycode(_display, XK_r);
- unsigned int keyCode_q = XKeysymToKeycode(_display, XK_q);
- if(event.keycode == keyCode_r) {
- _game.restart();
- draw();
- } else if(event.keycode == keyCode_q) {
- // Quit, somehow
- }
- }
- void HelloWorld::handleMousePress(const XButtonEvent& event) {
- if(event.button == 1) {
- Window rootWindow;
- int winX, winY;
- unsigned int width, height, borderWidth, bitDepth;
- XGetGeometry(_display, _window, &rootWindow, &winX, &winY, &width,
- &height, &borderWidth, &bitDepth);
- if((event.y >= 2 * STRING_HEIGHT) &&
- (event.y < (height - STRING_HEIGHT))) {
- int xStepSize = width / 3;
- int yStepSize = (height - STRING_HEIGHT * 3) / 3;
- int cellX = event.x / xStepSize;
- int cellY = (event.y - STRING_HEIGHT * 2) / yStepSize;
- if(_game.makeMove(cellX, cellY)) {
- if(_game.getGameState() == O_TURN) {
- _game.makeRandomMove();
- }
- draw();
- }
- }
- }
- }
- void HelloWorld::restartGame() {
- _game.restart();
- draw();
- }
- void HelloWorld::_drawO(const GC& gc, int x, int y, int w, int h) {
- XSetBackground(_display, gc, _whiteColor);
- XSetForeground(_display, gc, _blackColor);
- XFillArc(_display, _window, gc, x + w/10, y + h/10, (w*4)/5, (h*4)/5, 0,
- 360*64);
- XSetForeground(_display, gc, _whiteColor);
- XFillArc(_display, _window, gc, x + w/5, y + h/5, (w*3)/5, (h*3)/5, 0,
- 360*64);
- }
- void HelloWorld::_drawX(const GC& gc, int x, int y, int w, int h) {
- static const int POINT_COUNT = 12;
- static const XPoint RAW_CROSS[] = { {1, 2}, {2, 1}, {5, 4}, {8, 1}, {9, 2},
- {6, 5}, {9, 8}, {8, 9}, {5, 6}, {2, 9}, {1, 8}, {4, 5} };
- XPoint scaledCross[POINT_COUNT];
- for(int i = 0; i < POINT_COUNT; i++) {
- scaledCross[i].x = (RAW_CROSS[i].x * w) / 10 + x;
- scaledCross[i].y = (RAW_CROSS[i].y * h) / 10 + y;
- }
- XSetBackground(_display, gc, _whiteColor);
- XSetForeground(_display, gc, _blackColor);
- XFillPolygon(_display, _window, gc, scaledCross, POINT_COUNT, Nonconvex,
- CoordModeOrigin);
- }
- void HelloWorld::_drawString(const GC& gc, const char* str, int x, int y) {
- XDrawString(_display, _window, gc, x, y, str, strlen(str));
- }
- void HelloWorld::_drawStringCentered(const GC& gc, const char* str, int x, int y,
- int w, int h) {
- int direction, ascent, descent;
- XCharStruct strDimensions;
- XTextExtents(XQueryFont(_display, XGContextFromGC(gc)), str, strlen(str),
- &direction, &ascent, &descent, &strDimensions);
- int newX = x + (w - strDimensions.width) / 2;
- int newY = y + (h + strDimensions.ascent - strDimensions.descent) / 2;
- _drawString(gc, str, newX, newY);
- }
- int main() {
- Display* display = XOpenDisplay(NULL);
- if(!display) {
- cerr << "Unable to connect to X server." << endl;
- exit(1);
- }
- HelloWorld mainWindow(display);
- mainWindow.map();
- XFlush(display);
- XEvent event;
- while(true) {
- XNextEvent(display, &event);
- switch(event.type) {
- case ButtonPress:
- mainWindow.handleMousePress((XButtonEvent)event.xbutton);
- case Expose:
- if(event.xexpose.count == 0) {
- mainWindow.draw();
- }
- break;
- case KeyPress:
- mainWindow.handleKeyPress((XKeyEvent)event.xkey);
- default:
- break;
- }
- }
- XCloseDisplay(display);
- return 0;
- }
X11 五子棋的更多相关文章
- html+js+node实现五子棋线上对战,五子棋最简易算法
首先附上我的github地址,https://github.com/jiangzhenfei/five,线上实例:http://47.93.103.19:5900/client/ 线上实例,你可以随意 ...
- 自己写的HTML5 Canvas + Javascript五子棋
看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本.样式,帮助大众,成为受欢迎的人,感觉满羡慕的.我也想学会前端技术,变得受欢迎呀.于是心血来潮,开始学习前端知识,并写下了这 ...
- java swing 双人五子棋源代码
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; impo ...
- HTML5 五子棋 - JS/Canvas 游戏
背景介绍 因为之前用c#的winform中的gdi+,java图形包做过五子棋,所以做这个逻辑思路也就驾轻就熟,然而最近想温故html5的canvas绘图功能(公司一般不用这些),所以做了个五子棋,当 ...
- 阿里云ECS(Centos)开启X11的步骤
阿里云ECS(Centos)开启X11的步骤 1.修改sshd_config X11Forwarding yes 2.yum -y install xorg-x11-xauth xorg-x11-ut ...
- [收藏]C++简单五子棋
#include<iostream> #include<iomanip> using namespace std; ; //棋盘行数 ; //棋盘列数 char p[X][Y] ...
- jQuery网页版五子棋小游戏源码下载
体验效果:http://hovertree.com/texiao/game/4/ 网页五子棋源代码: <!DOCTYPE html> <html> <head> & ...
- js+html5双人五子棋(源码下载)
代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...
- jquery在线五子棋
在线五子棋试玩地址:http://keleyi.com/game/12/ 以下是完整代码,保存到html文件打开也可以玩: <!DOCTYPE html> <html> < ...
随机推荐
- 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展
[Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...
- 修改List报ConcurrentModificationException异常原因分析
使用迭代器遍历List的时候修改List报ConcurrentModificationException异常原因分析 在使用Iterator来迭代遍历List的时候如果修改该List对象,则会报jav ...
- C#中 如何执行带GO的sql 语句
C#中是不允许执行带GO的sql 语句的, 如何做呢? 思路就是将带GO的sql语句转化为分段执行, 但在同一事务内执行. 扩展方法是个很不错的主意, 但是尽量不要影响原来的cmd的一些东东, 如 c ...
- 弃用个人博客站重返CSDN缘由
最近悄然关闭了自己的个人博客小站,重新返回了CSDN写博客.恰逢周末,闲暇尚有,敲击键盘记录一下. 其实最初关闭个人基于SAE的个人博客站是一周前开始的,想想自己的博客已经有两周年多的时间了,刚刚创建 ...
- [APUE]进程控制(中)
一.wait和waitpid函数 当一个进程正常或异常终止时会向父进程发送SIGCHLD信号.对于这种信号系统默认会忽略.调用wait/waidpid的进程可能会: 阻塞(如果其子进程都还在运行); ...
- 基于session 的springMvc 国际化
项目中采用springMvc的框架,需要动态切换语言,找了一些资料,最后决定采用基于session的动态切换,实现动态切换中文,英文,韩文,其实就是把中文翻译成其他语言显示 springMvc国际化包 ...
- RabbitMQ Exchange类型详解
前言 在上一篇文章中,我们知道了RabbitMQ的消息流程如下: 但在具体的使用中,我们还需知道exchange的类型,因为不同的类型对应不同的队列和路由规则. 在rabbitmq中,exchange ...
- Spring实战——XML和JavaConfig的混合配置
前言 看了园龄已经两年多了,再不能写完内容直接点击发布,留下一片密密麻麻的文字让别人看的头昏脑涨.所以现在每次写完主要内容后,还需要对于格式稍稍调整下.那么有没有什么编辑模式能够在你写完文章后基本也把 ...
- .net 实战 根据configuration选项生成不同的config文件
项目开发过程中都会遇到的问题,开发环境的配置肯定是和生产环境不一样的,一直都是重复手动拷贝,但是配置太多拷贝的弊端就显现出来了,为了解决这个问题可以有几种方案: 1.Web.config Transf ...
- Python自动化开发-变量、数据类型和运算
一.变量 变量定义:Variables are used to store infomation to referrenced and manipulated in a computer progra ...