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> < ...
随机推荐
- cocos2d-x C++的do...while(0)另类使用方法
在C++中,有三种类型的循环语句:for, while, 和do...while, 但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视. 但是 ...
- xcode5向APP store上传应用的时候注意点
最近我在向appstore 上传应用的时候遇到了各种问题,由于网上的一些教程都是很久以前写的了,现在发布网站有些改动,所以自己走了很多弯路,不多说了,自己记录下犯下的错误吧.我是按照这片博客操作的:点 ...
- 输出一个string的所有排列情况
问题: 1.加入输入是{a,b,c}; 2.输出abc,acb,bac,bca,cab,cba; 代码描述: 1.递归遍历所有情况 2.方法FUN输入为:要排列的字符串char inp[];inp[] ...
- Unable to start activity异常的解决方案
当时我正在测试一个用户身份验证组件.使用的是android内置的Accounts API.当时的情况是,需要在App2中调用App1的用户身份验证组件,但是不知道为什么登入界面总是无法正常开启.后来我 ...
- 【ADO.Excel】ADO获取excel的Sheet集合
using (OleDbConnection connection = new OleDbConnection(GetConnectionString())) { connection.Open(); ...
- 强悍的跨平台开源多媒体中心XBMC介绍
强悍的跨平台开源多媒体中心XBMC介绍 最近都在了解Android下的音视频,因为最近需要做一个多媒体中心的APP,其中了解了一个开源项目XMBC,一个十分强大的开源多媒体中心,而且可以应用在多个平台 ...
- mybatis逆向工程生成代码
1 什么是逆向工程 mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml.po. ...
- thinkpad x230i U盘启动
现在的thinkpad的笔记本真麻烦,设置个U盘启动都不好使,网上找了好多都不管用,后来打电话问的售后电话才搞定,具体步骤如下: 按F1进bios的 [Security]中最下面Secure Boot ...
- Linux centos7环境下安装JDK的步骤详解
Linux centos7环境下安装JDK的步骤详解 测试root用户下JAVA版本 输入命令: java –version 1.先到Oracle官网里下载好jdk,网址如下: http://ww ...
- jvm内存增长问题排查
jvm内存增长问题排查 排查个jvm 内存占用持续增加的问题,纪录一下,引以为戒. 运维发现应用jvm内存占用在发布后回落,然后持续增高,,dump后分析一下: 占内存的大部分是这种名字相似的bean ...