游戏进阶玩法:当一方落下第4子仍未获胜时,则其落下的第1子会被拿掉,依次类推。
一、使用Visual Studio配置EasyX环境
EasyX是一个十分简单好用的
图形库
,相比于其他制作图形界面的工具而言要容易上手的多,十分适初学者使用。使用EasyX写的GUI程序十分
简洁、明了。
因为DEV-C++不兼容EasyX,所以用
Visual Studio
下载EasyX:
官网:
EasyX Graphics Library for C++
打开安装包,安装在Visual
二、代码编写游戏界面
1、画出棋盘
这只是画出游戏界面的一个函数而已
#include <graphics.h>//图形库头文件
#include<stdio.h>
#include<math.h>
void huamian() //画出棋盘
initgraph(800, 800);//创建图形窗口大小
IMAGE img; //准备图片
loadimage(NULL,"背景.jpg",800,800); //打开图片
setcolor(BLACK);设置线条黑色
for (int i = 150;i <= 450;i += 100) { //划线
line(i, 150, i, 450);
for (int i = 150;i <= 450;i += 100) {
line(150, i, 450, i);
其中loadimage函数是打开图片,需要把已经下载好的图片放在项目的文件中才能引用
2、获取鼠标的信息
鼠标点哪里,圈叉就在哪里
int i, j;
m = GetMouseMsg();//获取一个鼠标信息
int x, y,x1,y1,x2,y2;
for (int i = 2;i < 5;i++) {
for (int j = 2;j < 5;j++) {
if (abs(m.x - i * 100) < 50 && abs(m.y - j * 100) < 50) {
x = i * 100;
y = j * 100;
其中 if (abs(m.x - i * 100) < 50 && abs(m.y - j * 100) < 50) 的判断非常重要
如果没有鼠标点哪里,哪里就会出现O/X。
我们不可能每次都点中鼠标的正中间,所以就用abs取绝对值来确定鼠标的误差在什么范围内。
这样就可以允许鼠标点击出现偏差也能在格子正中间显示出O/X。
3、画圈叉
void isCircle(int x,int y) //画圆
setfillcolor(BLUE);//设置实心圆的颜色蓝色
solidcircle(x, y, 30); //画圆的坐标,半径
void isCha(int i, int j)//画叉
int x1, y1, x2, y2;
int x = (i + 2) * 100;
int y = (j + 2) * 100;
setcolor(RED);
x1 = x - 30;
y1 = y - 30;
x2 = x + 30;
y2 = y + 30;
line(x1, y1, x2, y2);
line(x2, y1, x1, y2);
由于是后期的函数,所以其中出现了很多其他数据
但不影响,其中最主要的是 solidcircle()和line()函数,
line(),画直线的函数,输入起点和终点的坐标即可
游戏界面的布局到这里就极其简陋的完成了。
三、核心进阶玩法设计
1、思路:
定义三维数组,chessBoard[a][x][y],其中x、y代表棋盘的横纵坐标都在(0、1、2)之间
而a代表在x、y这个位置上的属性,设计了有三种属性.
第0层代表该位置是否有棋子,0=没有,1=有。
第1层代表该位置是什么棋子,0=圆,1=叉
第2层代表该位置的深度(棋子存在的回合数),可取[0,7]
由于一方的棋子最多可以存在3个,下第四个时就要把第一个拿走,所以一颗棋子最多可以存在7个回合(呃~~~我定义了下一颗棋子就算一回合)
三维数组创立完毕
衔接问题:
将处理过后的鼠标横纵坐标(在[0,2]间的整数)传递给一个函数,该函数返回一个三维数组
然后遍历这个三维数组信息,画出相对应的棋子。鼠标再点下一个位置,函数就再返回一个新的数组给我,最后清空画面,重新遍历,画出棋子以达到消除棋子的目的。
2、上代码
设计三维数组的函数
int chessBoard[3][3][3] ; //属性(0:是否有棋子,1:(O)或(X)子,2;第几次下的),y,x
static int count = 0; //用于计数,static表示count变量作用域为当前目录,
void task1(int x, int y)
chessBoard[0][y][x] = 1;
if (count % 2 == 0)
chessBoard[1][y][x] = 0; // 0代表黑子 (O)
chessBoard[1][y][x] = 1; // 1代表白子(X)
count++;
addDepth();//增加深度 ,深度代表棋子存在的回合数
clearChess(); //清理深度
//output();
// printf("%d\n", count);
// printf("%d",chessBoard[0][y][x]);
void addDepth()
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (chessBoard[0][i][j] == 1) //如果有子
chessBoard[2][i][j] ++;//深度增加1
void clearChess() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (chessBoard[2][i][j] == 7)//如果一颗棋子存在7个回合则清零
chessBoard[2][i][j] = 0;//深度清零
chessBoard[0][i][j] = 0;//该位置没有棋子
头文件:封装成库函数
#pragma once
#ifndef task1_h
#define task1_h
void task1(int x, int y);
void addDepth();
void output();
void clearChess();
extern int chessBoard[3][3][3];
#endif
衔接过程:
if (m.uMsg == WM_LBUTTONDOWN) {//如果鼠标左键单击,处理鼠标的坐标成棋盘坐标
x = 0.01 * x - 2;
y = 0.01 * y - 2;
if (chessBoard[0][y][x] == 1) {//先判断这个地方是否有子,已经有子了就不能下了
continue;//以防重复点击相同位置
else {
task1(x, y);//把坐标给task函数处理
clearrectangle(0, 0, 800, 800);//清除画面
huamian1();//重新画棋盘
for (int i = 0;i < 3;i++) {//遍历棋盘的每一个位置
for (int j = 0;j < 3;j++) {
if (chessBoard[0][i][j] == 1) {//task返回给我三维数组,第0层代表是否有子
if (chessBoard[1][i][j] == 0) {//第一层代表是圆还是叉
isCircle(j, i);
else if (chessBoard[1][i][j] == 1) {
isCha(j, i);
其中huamian1()函数与huamian()函数相比,少了一句initgraph(800, 800); 若直接使用huamian()函数重新画一个棋盘则会一直创建新的窗口。(非常好玩)
int main()
huamian();
playChess();
while (1);//防止闪退
return 0;
四、完整的全家桶
链接:GitHub - Nebula-Yong/Tic-Tac-Toe: 高阶井字棋,一方下第四个子时,其第一个子会被收回,纯C打造,基于easyX制作GUI。vs的项目文件https://github.com/Nebula-Yong/Tic-Tac-Toe
井字棋游戏的C语言实现,两方玩家可以玩井字棋printf("请输入操作前的数字代号:\n1:新游戏\n2:退出\n");
scanf_s("%d", &op);
if (op == 2)
break;
else if (op == 1)
new_game();
else {
printf("请重新输入正确的数字:\n");
scanf_s("%d", &op);
if (op == 2)
break;
else if (op == 1)
new_game();
else {
printf("未知错误,请重新加载游戏\n");
printf("已退出游戏\n");
声明step变量为全局变量,这样函数内部就可以修改全局变量step的值x0和y0分别表示落子位置的左上角的x和y坐标。通过 index%3和 index // 3来计算出落子位置在棋盘上的行列坐标,并将其乘以117(每个格子的大小)来得到实际的像系坐标。x1和y1 则表示落子位置的右下角的x和y坐标,分别是 x0+117 和 y 0+ 117。说明在函数内部会对它进行修改或者读取。定义全局变量,设置一个列表写出所有赢的可能方式。
这是在之前[【C++ 程序】 井字棋游戏(人 VS Lv3电脑)(战绩统计版)的基础上运用 EasyX 图形库完成的可视化程序。
//This program is a simple tic-tac-toe game.
井字棋是一种在3 * 3格子上进行的连珠游戏,又称井字游戏。井字棋的游戏有两名玩家,其中一个玩家画圈,另一个玩家画叉,轮流在3 * 3格子上画上自己的符号,最先在横向、纵向、或斜线方向连成一条线的人为胜利方。如图1所示为画圈的一方为胜利者。