井字棋规则,鼠标点击交替落下“o”和“x”,在横3、竖3、斜3下判定获胜,如没有任意一方三连判定平局。
分析规则需求(初始化、绘画界面、游戏输入、游戏逻辑)
1.绘画棋盘格、o、x
2.鼠标移动九个格子内点击即放置棋子
3.o与x交替放置、已放置处不可放置
4.判断三连即胜利、九格子占满未胜利则平局
搭建框架
#include <iostream>
#include <windows.h>
using namespace std;
bool GameOver = false;
void Setup()//初始化
{
}
void Draw()//绘图
{
}
void Input()//输入
{
}
void Logic()//游戏逻辑
{
}
int main()
{
Setup();
while (!GameOver)
{
Draw();
Input();
Logic();
Sleep(15);
}
cin.get();
}
四个函数实现初始化、绘制图片、对输入处理、游戏逻辑
在while循环中反复“绘制图片、对输入处理、游戏逻辑”,其中sleep函数在windows文件中使图片刷新不那么快减少CPU占据。GameOver标志位标志游戏结束与否,在游戏中要习惯创建标志位。
Setup函数
void Setup()
{
GameOver = false;
initgraph(720, 720);
line(240, 0, 240, 720);
line(480, 0, 480, 720);
line(0, 240, 720, 240);
line(0, 480, 720, 480);
}
初始化initgraph函数创建720x720窗口,line画井字线,GameOver标志位设置为“游戏进行”,运行为。
Draw函数
void Draw()
{
if (LMouse == true && DrawCircleFlag == true)
{
if (CircleY < 240 && CircleX>0 && CircleX < 240)
{circle(120, 120, 100); Tictactoe[0] = 1;}
if (CircleY < 240 && CircleX>240 && CircleX < 480)
{circle(360, 120, 100); Tictactoe[1] = 1;}
if (CircleY < 240 && CircleX>480 && CircleX < 720)
{circle(600, 120, 100); Tictactoe[2] = 1;}
if (CircleY>240&&CircleY < 480 && CircleX>0 && CircleX < 240)
{circle(120, 360, 100);Tictactoe[3] = 1;}
if (CircleY > 240 && CircleY < 480 && CircleX>240 && CircleX < 480)
{circle(360, 360, 100); Tictactoe[4] = 1;}
if (CircleY > 240 && CircleY < 480 && CircleX>480 && CircleX < 720)
{circle(600, 360, 100); Tictactoe[5] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>0 && CircleX < 240)
{circle(120, 600, 100); Tictactoe[6] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>240 && CircleX < 480)
{circle(360, 600, 100); Tictactoe[7] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>480 && CircleX < 720)
{circle(600, 600, 100); Tictactoe[8] = 1;}
LMouse = false;
DrawCircleFlag = false;
CrossFlag = true;
}
if (LMouse == true && CrossFlag == true)
{
if (CircleY < 240 && CircleX>0 && CircleX < 240)
{ line(0, 0, 240, 240); line(240, 0, 0, 240); Tictactoe[0] = -1;}
if (CircleY < 240 && CircleX>240 && CircleX < 480)
{ line(240, 0, 480, 240); line(480, 0, 240, 240); Tictactoe[1] = -1;}
if (CircleY < 240 && CircleX>480 && CircleX < 720)
{ line(480, 0, 720, 240); line(720, 0, 480, 240); Tictactoe[2] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>0 && CircleX < 240)
{ line(0, 240, 240, 480); line(240, 240, 0, 480); Tictactoe[3] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>240 && CircleX < 480)
{ line(240, 240, 480, 480); line(480, 240, 240, 480); Tictactoe[4] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>480 && CircleX < 720)
{ line(480, 240, 720, 480); line(720, 240, 480, 480); Tictactoe[5] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>0 && CircleX < 240)
{ line(0, 480, 240, 720); line(240, 480, 0, 720); Tictactoe[6] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>240 && CircleX < 480)
{ line(240, 480, 480, 720); line(480, 480, 240, 720); Tictactoe[7] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>480 && CircleX < 720)
{ line(480, 480, 720, 720); line(720, 480, 480, 720); Tictactoe[8] = -1;}
LMouse = false;
DrawCircleFlag = true;
CrossFlag = false;
}
}
我们下棋顺序是先o后x交替落子。if语句判断格子位置然后根据坐标绘制O与X,并将O处标记为1,X处标记为-1。我们看下整体代码。
#include <iostream>
#include <graphics.h>
#include <windows.h>
using namespace std;
bool GameOver = false;
bool LMouse;
bool DrawCircleFlag;
bool CrossFlag;
int Tictactoe[9] =
{
0,0,0,
0,0,0,
0,0,0
};
void Setup()//初始化
{
GameOver = false;
initgraph(720, 720);
line(240, 0, 240, 720);
line(480, 0, 480, 720);
line(0, 240, 720, 240);
line(0, 480, 720, 480);
DrawCircleFlag = true;
CrossFlag = false;
}
void Draw()//绘画
{
if (LMouse == true && DrawCircleFlag == true)
{
if (CircleY < 240 && CircleX>0 && CircleX < 240)
{circle(120, 120, 100); Tictactoe[0] = 1;}
if (CircleY < 240 && CircleX>240 && CircleX < 480)
{circle(360, 120, 100); Tictactoe[1] = 1;}
if (CircleY < 240 && CircleX>480 && CircleX < 720)
{circle(600, 120, 100); Tictactoe[2] = 1;}
if (CircleY>240&&CircleY < 480 && CircleX>0 && CircleX < 240)
{circle(120, 360, 100);Tictactoe[3] = 1;}
if (CircleY > 240 && CircleY < 480 && CircleX>240 && CircleX < 480)
{circle(360, 360, 100); Tictactoe[4] = 1;}
if (CircleY > 240 && CircleY < 480 && CircleX>480 && CircleX < 720)
{circle(600, 360, 100); Tictactoe[5] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>0 && CircleX < 240)
{circle(120, 600, 100); Tictactoe[6] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>240 && CircleX < 480)
{circle(360, 600, 100); Tictactoe[7] = 1;}
if (CircleY > 480 && CircleY < 720 && CircleX>480 && CircleX < 720)
{circle(600, 600, 100); Tictactoe[8] = 1;}
LMouse = false;
DrawCircleFlag = false;
CrossFlag = true;
}
if (LMouse == true && CrossFlag == true)
{
if (CircleY < 240 && CircleX>0 && CircleX < 240)
{ line(0, 0, 240, 240); line(240, 0, 0, 240); Tictactoe[0] = -1;}
if (CircleY < 240 && CircleX>240 && CircleX < 480)
{ line(240, 0, 480, 240); line(480, 0, 240, 240); Tictactoe[1] = -1;}
if (CircleY < 240 && CircleX>480 && CircleX < 720)
{ line(480, 0, 720, 240); line(720, 0, 480, 240); Tictactoe[2] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>0 && CircleX < 240)
{ line(0, 240, 240, 480); line(240, 240, 0, 480); Tictactoe[3] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>240 && CircleX < 480)
{ line(240, 240, 480, 480); line(480, 240, 240, 480); Tictactoe[4] = -1;}
if (CircleY > 240 && CircleY < 480 && CircleX>480 && CircleX < 720)
{ line(480, 240, 720, 480); line(720, 240, 480, 480); Tictactoe[5] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>0 && CircleX < 240)
{ line(0, 480, 240, 720); line(240, 480, 0, 720); Tictactoe[6] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>240 && CircleX < 480)
{ line(240, 480, 480, 720); line(480, 480, 240, 720); Tictactoe[7] = -1;}
if (CircleY > 480 && CircleY < 720 && CircleX>480 && CircleX < 720)
{ line(480, 480, 720, 720); line(720, 480, 480, 720); Tictactoe[8] = -1;}
LMouse = false;
DrawCircleFlag = true;
CrossFlag = false;
}
}
void Input()//输入
{
}
void Logic()//游戏逻辑
{
}
int main()
{
Setup();
while (!GameOver)
{
Draw();
Input();
Logic();
Sleep(15);
}
cin.get();
}
至此我们完成了绘画棋盘、O、X并对数组进行标记。DrawCircleFlag与CrossFlag交替设置为true则可以交替绘画OX。
Input函数
void Input()
{
ExMessage msg;
while (peekmessage(&msg,EX_MOUSE))
{
if (msg.message == WM_LBUTTONDOWN)
{
LMouse = msg.lbutton;
CircleX = msg.x;
CircleY = msg.y;
}
}
}
EasyX文档中有消息结构体,peekmessage函数获取鼠标消息,如果获取到鼠标左键将LMouse标志位置为1,获取坐标交给O的xy,此时运行效果已经是
但是我们看到既是O或X三联,游戏也没有结束,所以我们继续编写逻辑函数
Logic函数
记得我们的额数组初始化0到8都置为0,格子标记O置为1,格子标记X置为-1,此时三联相加为3或-3就是有人获胜。
void Logic()
{
settextstyle(36, 0, _T("O WIN"));
settextstyle(36, 0, _T("X WIN"));
if ((Tictactoe[0] + Tictactoe[1] + Tictactoe[2]== 3)||
(Tictactoe[3] + Tictactoe[4] + Tictactoe[5] == 3)||
(Tictactoe[6] + Tictactoe[7] + Tictactoe[8] == 3))
{
outtextxy(360,360,"O WIN"); GameOver = true;
}
if ((Tictactoe[0] + Tictactoe[1] + Tictactoe[2] == -3) ||
(Tictactoe[3] + Tictactoe[4] + Tictactoe[5] == -3) ||
(Tictactoe[6] + Tictactoe[7] + Tictactoe[8] == -3))
{
outtextxy(360, 360, "X WIN"); GameOver = true;
}
if ((Tictactoe[0] + Tictactoe[3] + Tictactoe[6] == 3) ||
(Tictactoe[1] + Tictactoe[4] + Tictactoe[7] == 3)||
(Tictactoe[2] + Tictactoe[5] + Tictactoe[8] == 3) )
{
outtextxy(360, 360, "O WIN"); GameOver = true;
}
if ((Tictactoe[0] + Tictactoe[3] + Tictactoe[6] == -3) ||
(Tictactoe[1] + Tictactoe[4] + Tictactoe[7] == -3) ||
(Tictactoe[2] + Tictactoe[5] + Tictactoe[8] == -3) )
{
outtextxy(360, 360, "X WIN"); GameOver = true;
}
if((Tictactoe[0] + Tictactoe[4] + Tictactoe[8] == 3)|| (Tictactoe[2] + Tictactoe[4] + Tictactoe[6] == 3))
{
outtextxy(360, 360, "O WIN"); GameOver = true;
}
if ((Tictactoe[0] + Tictactoe[4] + Tictactoe[8] == -3) || (Tictactoe[2] + Tictactoe[4] + Tictactoe[6] == -3))
{
outtextxy(360, 360, "X WIN"); GameOver = true;
}
}
至此井字棋游戏就制作完成了,
settextstyle(36, 0, _T("O WIN"));这个函数确立了打印字符串的大小详细函数解释可以去EasyX文档
总结
初始化界面,输入鼠标函数设置鼠标标志位、O绘画标志位,对格子坐标分析绘画OX、对九宫格数组设置标志1与-1,对游戏获胜做判断。