这个五子棋,有单人模式和双人模式,完全是c语言写的,所以其实就是只有一些基本逻辑,但是我也经常输,hhhh。(半年前写的,有很多地方看起来就,所以想优化一下,hhhh)

用一个数组维护棋盘的棋子,例如,-1为白棋,1为黑棋,0为无棋每次下完棋都根据数组展示一下棋盘。(当然是用鼠标)。
用户界面
这里的单人模式和双人模式是打字的看上去就不是很好看,其实可以用图片来代替一下,看清来就不会像这个看起来那么难受。好像看起来更丑了,,,,,但是我感觉是因为图片没找好。修改后的代码。
void menu()
{
for (int x = 0; x < 30; x++)for (int y = 0; y < 30; y++)qizi[x][y] = 100;
for (int x = 6; x < 25; x++)for (int y = 0; y < 25; y++)qizi[x][y] = 0;
initgraph(800, 496, EW_SHOWCONSOLE);
setbkcolor(WHITE);
cleardevice();
IMAGE x,a1,a2,b1,b2;
ExMessage c;
setfillcolor(RGB(137, 207, 180));
settextcolor(BLUE);
settextstyle(35, 20, "微软雅黑");
loadimage(&x, "hhh.jpg");
loadimage(&a1, "单人模式按钮图片.png");
loadimage(&a2, "单人模式按钮图片2.png");
loadimage(&b1, "双人模式按钮.png");
loadimage(&b2, "双人模式按钮2.png");
BeginBatchDraw();
putimage(0, 0, &x);
transparentimage(200, 350, &a2, &a1);
transparentimage(400, 350, &b2, &b1);
EndBatchDraw();
while (1) {
if (peekmessage(&c, EM_MOUSE)&&c.lbutton) {
if(c.x>213&&c.x<332&&c.y>360&&c.y<399)
{
game1();
return;
}
if(c.x>413&&c.x<532&&c.y>360&&c.y<399)
{
game2();
return;
}
printf("%d %dn", c.x, c.y);
}
}
}
双人模式
void game2()
{
closegraph();
int x1, y1,cc=0;
char arr[] = "黑方胜利";
char brr[] = "白方胜利";
settextcolor(RED);
settextstyle(20, 20, "微软雅黑");
initgraph(855,856, EW_SHOWCONSOLE);
IMAGE x;
ExMessage c;
loadimage(&x, "棋盘.jpg");
putimage(0, 0, &x);
while (1) {
getmessage(&c, EM_MOUSE);
switch (c.message) {
case WM_LBUTTONDOWN:printf("%d %d %dn", c.x, c.y, sum); if (c.x >= 47 && c.y >= 54&&c.x<=804&&c.y<=807) {
if (sum % 2 != 0) changeh(c.x, c.y);
else changeb(c.x, c.y);
}
break;
}
map();
cc=check();
if (cc != 0) {
if (cc == 1) outtextxy(20, 20, arr);
else outtextxy(20, 20, brr);
system("pause");
return ;
}
}
}
这个将黑白棋的函数分开了,其实没必要,完全可以传入参数,来简化代码,还有下棋之后要清空整个屏幕就很浪费。
void game2()
{
closegraph();
loadimage(&x3, "白棋真.jpg");
loadimage(&x31, "白棋假.jpg");
loadimage(&x2, "黑棋真.jpg");
loadimage(&x21, "黑棋假.jpg");
int x1, y1,cc=0,sum=0;
char arr[] = "黑方胜利";
char brr[] = "白方胜利";
settextcolor(RED);
settextstyle(20, 20, "微软雅黑");
initgraph(855,856, EW_SHOWCONSOLE);
IMAGE x;
ExMessage c;
loadimage(&x, "棋盘.jpg");
putimage(0, 0, &x);
while (1)
{
if (peekmessage(&c, EM_MOUSE) && c.lbutton&& c.x >= 47 && c.y >= 54 && c.x <= 804 && c.y <= 807)
{
printf("kkkn");
if (sum % 2 == 0 && chang(c.x, c.y, 1))
{
sum++;
map(c.x, c.y);
cc = check(1);
}
else if (sum % 2 != 0 && chang(c.x, c.y, -1))
{
sum++;
map(c.x, c.y);
cc = check(-1);
}
if (cc != 0) {
if (cc == 1) outtextxy(20, 20, arr);
else outtextxy(20, 20, brr);
system("pause");
return;
}
}
}
}
单人模式
这个判断应该下在哪其实就是枚举,当然这个思路我是不会改变,也不知道怎么改。改了一下下后就是
void game1()
{
closegraph();
int a = 0,cc=0,b=0;
initgraph(800, 801, EW_SHOWCONSOLE);
IMAGE x;
ExMessage c;
char arr[] = "你赢了";
char brr[] = "你输了";
settextcolor(RED);
settextstyle(20, 20, "微软雅黑");
loadimage(&x, "棋盘.jpg");
putimage(0, 0, &x);
a=heibai();
while (1)
{
getmessage(&c, EM_MOUSE);//一定要接受信息
if ( c.lbutton && c.x >= 47 && c.y >= 54 && c.x <= 804 && c.y <= 807&&a%2!=0)
{
printf("kkkn");
if (chang(c.x, c.y, 1))
{
a++;
map(c.x, c.y);
cc = check(5,1);
}
}
else
{
ai(), a++;
cc = check(5,-1);
}
if (cc != 0) {
if (cc == 1) outtextxy(20, 20, arr);
else outtextxy(20, 20, brr);
system("pause");
return;
}
}
}
单人模式的具体实现
判断游戏结束

正常来说都需要判断8个方向,但是其实考虑四个方向就行,其余四个方向在判断其他棋子时会考虑到,并且可以加入参数来判断几个时为胜利。
int check(int l,int e)
{
for (int x = 6; x < 25; x++)
{
for (int y = 6; y < 25; y++)
for (int k = 0; k < 4; k++)
{
bool flag = true;
for (int z = 0; z < l; z++)
{
if (qizi[z * dx[k] + x][z * dy[k] + y ]!= e)flag = false;
}
if (flag)return e;
}
}
return 0;
}
枚举不同情况
void ai()
{
}
其实就是判断好每种情况的优先级,例如此时场面黑棋和白棋都有4个都有获胜的可能性,但此时你是白棋,且轮到你下棋,白棋就可以获胜,但如果你黑棋是4个,白棋是三个,就需要去堵住黑棋获胜。
但是如果知道应该堵住哪个位置就可以让黑棋不能获胜呢,这个就需要用到check()了,枚举每个位置如果这里是黑棋看黑棋是否获胜。
当然为了更加只能要枚举更多情况,最后也要搞了随机,当然如果考虑完也可以不搞。
int check(int l, int e, bool st = false, int x = 0, int y = 0)
{
if (st)
{
for (int k = 0; k < 4; k++)
{
bool flag = true;
for (int z = 0; z < l; z++)
{
if (qizi[z * dx[k] + x][z * dy[k] + y] != e)flag = false;
}
if (flag)return e;
}
for (int i = 0; i < 8; i++)
{
for (int j = 1; j < l; j++)
{
int a = x + dx[i] * j, b = y + dy[i] * j;
for (int k = 0; k < 4; k++)
{
bool flag = true;
for (int z = 0; z < l; z++)
{
if (qizi[z * dx[k] + a][z * dy[k] + b] != e)flag = false;
}
if (flag)return e;
}
}
}
}
else
{
for (int x = 6; x < 25; x++)
{
for (int y = 6; y < 25; y++)
for (int k = 0; k < 4; k++)
{
bool flag = true;
for (int z = 0; z < l; z++)
{
if (qizi[z * dx[k] + x][z * dy[k] + y] != e)flag = false;
}
if (flag)return e;
}
}
}
return 0;
}
应该还能优化的,,,,
最终代码#include相关素材#include #include #include #include #include #pragma comment(lib,"Winmm.lib") int qizi[30][30] = { 0 }; IMAGE x2, x3, x21, x31; int dx[8] = { -1, -1, -1, 0, 1, 1, 1, 0 }; int dy[8] = { -1, 0, 1, 1, 1, 0, -1, -1 }; int mx[2] = { -1,1 }; void bgm()//背景音乐 { mciSendString("open 1.mp3 ", NULL, 0, NULL); mciSendString("play 1.mp3 repeat", NULL, 0, NULL); } int check(int l, int e, bool st = false, int x = 0, int y = 0) { if (st) { for (int k = 0; k < 4; k++) { bool flag = true; for (int z = 0; z < l; z++) { if (qizi[z * dx[k] + x][z * dy[k] + y] != e)flag = false; } if (flag)return e; } for (int i = 0; i < 8; i++) { for (int j = 1; j < l; j++) { int a = x + dx[i] * j, b = y + dy[i] * j; for (int k = 0; k < 4; k++) { bool flag = true; for (int z = 0; z < l; z++) { if (qizi[z * dx[k] + a][z * dy[k] + b] != e)flag = false; } if (flag)return e; } } } } else { for (int x = 6; x < 25; x++) { for (int y = 6; y < 25; y++) for (int k = 0; k < 4; k++) { bool flag = true; for (int z = 0; z < l; z++) { if (qizi[z * dx[k] + x][z * dy[k] + y] != e)flag = false; } if (flag)return e; } } } return 0; } void transparentimage(int x, int y, IMAGE* srcimg, IMAGE* maskimg) { putimage(x, y, maskimg, SRCAND); putimage(x, y, srcimg, SRCPAINT); } void map(int x, int y, bool st = false) { int a = x / 41 + 5, b = y / 41 + 5, c = x % 41, d = y % 41; if (st)a = x, b = y; if (qizi[a][b] == 1)transparentimage(41 * (a - 6) + 38, 41 * (b - 6) + 43, &x2, &x21); if (qizi[a][b] == -1)transparentimage(41 * (a - 6) + 38, 41 * (b - 6) + 43, &x3, &x31); } bool chang(int x, int y, int e) { int a = x / 41 + 5, b = y / 41 + 5, c = x % 41, d = y % 41; if (7 <= c && c <= 27 && 12 <= d && 32 >= d && qizi[a][b] == 0) { qizi[a][b] = e; return true; } return false; } void ai() { for (int l = 5; l > 1; l--)for (int z = 0; z < 2; z++) for (int x = 6; x < 25; x++)for (int y = 6; y < 25; y++) { if (qizi[x][y] == 0) { qizi[x][y] = mx[z]; if (check(l, mx[z], true, x, y) == mx[z]) { if (z == 1)qizi[x][y] = -1; map(x, y, true); printf("%d %d %d %dn", l, z, x, y); return; } else qizi[x][y] = 0; } } qizi[17][17] = -1; map(17, 17, true); } int heibai() { HWND hh = GetHWnd(); SetWindowText(hh, "五子棋"); int a = MessageBox(hh, "是否选择先手", "提示", MB_OKCANCEL); if (a == IDOK)return 1; else return 0; } void game1() { closegraph(); int a = 0, cc = 0, b = 0; initgraph(800, 801, EW_SHOWCONSOLE); IMAGE x; ExMessage c; char arr[] = "你赢了"; char brr[] = "你输了"; settextcolor(RED); settextstyle(20, 20, "微软雅黑"); loadimage(&x, "棋盘.jpg"); putimage(0, 0, &x); a = heibai(); while (1) { if (a % 2 != 0) { getmessage(&c, EM_MOUSE); if (c.lbutton && c.x >= 47 && c.y >= 54 && c.x <= 804 && c.y <= 807) { if (chang(c.x, c.y, 1)) { a++; map(c.x, c.y); cc = check(5, 1); } } } else { ai(); a++; cc = check(5, -1); } if (cc != 0) { if (cc == 1) outtextxy(20, 20, arr); else outtextxy(20, 20, brr); system("pause"); return; } } } void game2() { closegraph(); int x1, y1, cc = 0, sum = 0; char arr[] = "黑方胜利"; char brr[] = "白方胜利"; settextcolor(RED); settextstyle(20, 20, "微软雅黑"); initgraph(855, 856, EW_SHOWCONSOLE); IMAGE x; ExMessage c; loadimage(&x, "棋盘.jpg"); putimage(0, 0, &x); while (1) { if (peekmessage(&c, EM_MOUSE) && c.lbutton && c.x >= 47 && c.y >= 54 && c.x <= 804 && c.y <= 807) { if (sum % 2 == 0 && chang(c.x, c.y, 1)) { sum++; map(c.x, c.y); cc = check(3, 1); } else if (sum % 2 != 0 && chang(c.x, c.y, -1)) { sum++; map(c.x, c.y); cc = check(3, -1); } if (cc != 0) { if (cc == 1) outtextxy(20, 20, arr); else outtextxy(20, 20, brr); system("pause"); return; } } } } void menu() { for (int x = 0; x < 30; x++)for (int y = 0; y < 30; y++)qizi[x][y] = 1000; for (int x = 6; x < 25; x++)for (int y = 6; y < 25; y++)qizi[x][y] = 0; initgraph(800, 496, EW_SHOWCONSOLE); setbkcolor(WHITE); cleardevice(); IMAGE x, a1, a2, b1, b2; ExMessage c; setfillcolor(RGB(137, 207, 180)); settextcolor(BLUE); settextstyle(35, 20, "微软雅黑"); loadimage(&x, "hhh.jpg"); loadimage(&a1, "单人模式按钮图片.png"); loadimage(&a2, "单人模式按钮图片2.png"); loadimage(&b1, "双人模式按钮.png"); loadimage(&b2, "双人模式按钮2.png"); loadimage(&x3, "白棋真.jpg"); loadimage(&x31, "白棋假.jpg"); loadimage(&x2, "黑棋真.jpg"); loadimage(&x21, "黑棋假.jpg"); BeginBatchDraw(); putimage(0, 0, &x); transparentimage(200, 350, &a2, &a1); transparentimage(400, 350, &b2, &b1); EndBatchDraw(); while (1) { if (peekmessage(&c, EM_MOUSE) && c.lbutton) { if (c.x > 213 && c.x < 332 && c.y>360 && c.y < 399) { game1(); return; } if (c.x > 413 && c.x < 532 && c.y>360 && c.y < 399) { game2(); return; } printf("%d %dn", c.x, c.y); } } } int main() { bgm(); menu(); return 0; }
阿里云盘



