这是一个围棋小游戏
2021-2-9 ~ 2021-5-8
(2)
游戏说明
这是一个围棋小游戏。
1. 真实模拟现实围棋下棋环境,可手动提掉棋子,享受提子的快乐。
2. 如今许多网棋让许多棋手忘却了学习形势判断,点目等重要能力,而这款游戏将带你回到围棋的原始时期,取消了ai形势判断,取消了ai点目判断,让你在围棋上返璞归真,棋力更加精湛。
游戏操作说明
左键:下棋
右键:消除棋子
中键:停一手
程序运行效果
源码
/*
* 程序名称: 围棋
* 作者: tofu
* 编译环境: VC2019,EasyX_20210224
* 最后修改时间:2021-05-08
* ********* 规则 **********
* 左键: 落子
* 右键: 消除棋子
* 中键: 停一手
* *************************/
#include <graphics.h>
int GoBoard[19][19]; // 棋盘数组
MOUSEMSG m; // 鼠标对象
bool Go = 1; // 棋子 fill 颜色 1:黑色 0:白色 2:无子
int x, y, jud = 0; // 记录当前选定点 x,y;
// 判断是否更新选定点 jud 1:锁定 0:解锁
int* Fall_x = new int(-1), * Fall_y = new int(-1); // 记录已落棋子的数组坐标
void init(void); // 初始化
void game(int, int); // 游戏循环
void draw(int Dx, int Dy); // 绘制(清除)选定点
int main(void)
{
// 初始化事件
init();
// 游戏开始
while (true)
{
game(*Fall_x, *Fall_y);
}
}
/*
* 界面初始化
*
*/
void init(void)
{
// 初始化绘图界面
initgraph(700, 700);
setfillcolor(RGB(233, 206, 156)); // 棋盘 fill 颜色
solidrectangle(0, 0, 700, 700);
// 初始化棋盘
for (int i = 0; i < 19; i++)
{ // 初始化棋盘数组
for (int j = 0; j < 19; j++)
{
GoBoard[i][j] = 2;
}
}
setlinecolor(BLACK); // 设置网格 line 颜色
for (int i = 2; i < 20; i++)
{ // 绘制网格
rectangle(35, 35, 665, 35 * i);
rectangle(35, 35, 35 * i, 665);
}
setfillcolor(BLACK); // 定点 fill 颜色 绘制星点
solidcircle(560, 140, 3);
solidcircle(350, 140, 3);
solidcircle(140, 140, 3);
solidcircle(560, 560, 3);
solidcircle(350, 560, 3);
solidcircle(140, 560, 3);
solidcircle(560, 350, 3);
solidcircle(350, 350, 3);
solidcircle(140, 350, 3);
}
/*
* 游戏循环体
*
*/
void game(int fall_x, int fall_y)
{
m = GetMouseMsg();
// 设置棋子 fill 颜色
if (Go == 1)
{
setfillcolor(BLACK);
setlinecolor(WHITE);
}
else if (Go == 0)
{
setfillcolor(WHITE);
setlinecolor(BLACK);
}
// 鼠标事件
switch (m.uMsg)
{
// 选定落子区域
case WM_MOUSEMOVE:
if ((m.x + 18) > 35 && (m.x + 18) < 682 &&
(m.y + 18) > 35 && (m.y + 18) < 682 &&
GoBoard[(m.x + 18) / 35 - 1][(m.y + 18) / 35 - 1] == 2)
{ // 判断边界 是否已有落子
if (jud == 0)
{
x = int((m.x + 18) / 35); // 记录当前选定点
y = int((m.y + 18) / 35);
jud = 1; // 锁定选定点
setlinecolor(BLACK);
draw((m.x + 18) / 35, (m.y + 18) / 35); // 绘制选定点区域
}
}
if (GoBoard[x - 1][y - 1] == 2 &&
(x != int((m.x + 18) / 35) || y != int((m.y + 18) / 35)))
{ // 判断选定点是否变动
jud = 0; // 解锁上一选定点 重新记录
setlinecolor(RGB(233, 206, 156)); // 还原上一选定点
draw(x, y);
}
break;
// 落子
case WM_LBUTTONDOWN:
if ((m.x + 18) > 35 && (m.x + 18) < 682 &&
(m.y + 18) > 35 && (m.y + 18) < 682 &&
GoBoard[(m.x + 18) / 35 - 1][(m.y + 18) / 35 - 1] == 2)
{ // 判断边界 是否已有落子
solidcircle(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, 15); // 落子
GoBoard[(m.x + 18) / 35 - 1][(m.y + 18) / 35 - 1] = Go; // 更新棋盘数组
draw(((m.x + 18) / 35), ((m.y + 18) / 35)); // 标记此次落子标记点
static int Bx = -1, By = -1;
if (Go == 1)
{ // 消除的色彩选择
setlinecolor(WHITE);
}
else if (Go == 0)
{
setlinecolor(BLACK);
}
if ((Bx != -1) && (By != -1) && (GoBoard[Bx - 1][By - 1] != 2))
{
draw(Bx, By); // 消除上一落子标记点
}
Bx = ((m.x + 18) / 35); // 记录此次落子数组位点
By = ((m.y + 18) / 35);
jud = 0; // 解锁该选定点, 重新记录
Go = !Go; // 取反棋子
}
break;
// 清除棋子
case WM_RBUTTONDOWN:
if ((m.x + 18) > 35 && (m.x + 18) < 682 &&
(m.y + 18) > 35 && (m.y + 18) < 682 &&
GoBoard[(m.x + 18) / 35 - 1][(m.y + 18) / 35 - 1] != 2)
{
setfillcolor(RGB(233, 206, 156)); // 设置 fill 颜色
solidcircle(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, 15); // 清除
GoBoard[(m.x + 18) / 35 - 1][(m.y + 18) / 35 - 1] = 2; // 更新棋盘数组
setlinecolor(BLACK); // 还原网格
if ((m.x + 18) / 35 == 1 && (m.y + 18) / 35 == 1)
{ // 左上角
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
}
else if ((m.x + 18) / 35 == 19 && (m.y + 18) / 35 == 1)
{ // 右上角
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
}
else if ((m.x + 18) / 35 == 1 && (m.y + 18) / 35 == 19)
{ // 左下角
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
else if ((m.x + 18) / 35 == 19 && (m.y + 18) / 35 == 19)
{ // 右下角
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
else if ((m.x + 18) / 35 == 1)
{ // 左侧
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
else if ((m.x + 18) / 35 == 19)
{ // 右侧
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
else if ((m.y + 18) / 35 == 1)
{ // 上侧
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35);
}
else if ((m.y + 18) / 35 == 19)
{ // 下侧
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
else if (((m.x + 18) / 35 == 4 || (m.x + 18) / 35 == 10 || (m.x + 18) / 35 == 16) &&
((m.y + 18) / 35 == 4 || (m.y + 18) / 35 == 10 || (m.y + 18) / 35 == 16))
{ // 星位
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
setfillcolor(BLACK); // 定点 fill 颜色 绘制星点
solidcircle(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35, 3);
}
else
{
line(((m.x + 18) / 35) * 35 - 15, ((m.y + 18) / 35) * 35, ((m.x + 18) / 35) * 35 + 15, ((m.y + 18) / 35) * 35);
line(((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 + 15, ((m.x + 18) / 35) * 35, ((m.y + 18) / 35) * 35 - 15);
}
}
break;
// 停一手
case WM_MBUTTONDOWN:
Go = !Go; // 取反棋子
break;
}
}
/*
* 绘制选定框
* Dx,Dy:数组位点 x,y 坐标
*/
void draw(int Dx, int Dy)
{
line(Dx * 35 - 5, Dy * 35 - 5, Dx * 35 - 10, Dy * 35 - 5);
line(Dx * 35 - 5, Dy * 35 - 5, Dx * 35 - 5, Dy * 35 - 10);
line(Dx * 35 + 5, Dy * 35 - 5, Dx * 35 + 10, Dy * 35 - 5);
line(Dx * 35 + 5, Dy * 35 - 5, Dx * 35 + 5, Dy * 35 - 10);
line(Dx * 35 - 5, Dy * 35 + 5, Dx * 35 - 10, Dy * 35 + 5);
line(Dx * 35 - 5, Dy * 35 + 5, Dx * 35 - 5, Dy * 35 + 10);
line(Dx * 35 + 5, Dy * 35 + 5, Dx * 35 + 10, Dy * 35 + 5);
line(Dx * 35 + 5, Dy * 35 + 5, Dx * 35 + 5, Dy * 35 + 10);
}