一、开始的思路
1.从三子棋开始,先不考虑扩展
(1)、 打印棋盘
打印一个棋盘,如何打印呢?先考虑下棋的位置,是三行三列,所以定义一个数组c[3][3],如何让这个棋盘有分割线呢?分别打印,第一行先输出 a[0][0] | a[0][1] | a[0][2] ,第二行输出—|—|—,依次类推(见函数void dayin (int a[ROW][COL], int row,int col))。打印出的棋盘,每个数值并不为‘ ’,使用循环赋值,使数组元素全为‘ ’(见函数void empty( int a[ROW][COL], int row,int col) ),效果如下图
(2)、开始下棋,
写一个菜单,一个简单的函数,内为简单的printf输出即可(见函数void menu () )。用switch,keys语句接收一个数字,判断是否开始游戏(见函数void get_panduan())。
开始下棋分为两布,玩家下棋(见函数void player_move(int a[ROW][COL], int row, int col)
)和电脑下棋(见函数void computer_move(int a[ROW][COL], int row, int col)
)。电脑下棋我们采用生成随机坐标的方法。
(3)、判断输赢
两种情况(见函数int who_win(int a[ROW][COL], int row, int col)
)
1、棋盘满时或未满时,有一方已连成三个
行三个
列三个
对角线三个
反对角线三个
(有一方赢时 函数返回1,结束游戏,否则不返回游戏继续)
2、棋盘已满,没有人赢,输出平局。
//game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h> //对应printf,scanf
#include<string.h> //对应sizeof
#include<stdlib.h> //对应rand()随机生成数
#define ROW 3
#define COL 3
void empty(int a[ROW][COL], int row,int col);
void dayin(int a[ROW][COL], int row, int col);
int full(int a[ROW][COL], int row,int col);
void computer_move(int a[ROW][COL], int row, int col);
void player_move(int a[ROW][COL], int row, int col);
int who_win(int a[ROW][COL], int row, int col);
//game.c 在这里定义游戏函数,核心
#include"game.h"
void empty( int a[ROW][COL], int row,int col) //1.定义一个将数组致空的循环
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j <col; j++)
{
a[i][j] = ' ';
}
}
}
void dayin (int a[ROW][COL], int row,int col) //2.打印初始空棋盘
{
int i = 0, j = 0;
for (j = 0; j <= 2; j++)
{
printf(" %c ",a[0][j]);
if (j < 2)
printf("|");
}
printf("\n"); //打印出第一行的 | | ;
for (j = 0; j <= 2; j++)
{
printf("---");
if (j < 2)
printf("|");
}
printf("\n");
for (j = 0; j <= 2; j++) //打印分隔---|---|---
{
printf(" %c ",a[1][j]);
if (j < 2)
printf("|"); //打印出第二行的 | | ;
}
printf("\n");
for (j = 0; j <= 2; j++) //打印分隔---|---|---
{
printf("---");
if (j < 2)
printf("|");
}
printf("\n");
for (j = 0; j <= 2; j++)
{
printf(" %c ",a[2][j]);
if (j < 2)
printf("|"); //打印出第三行的 | | ;
}
printf("\n\n");
}
int full(int a[ROW][COL],int b, int c) // 一个判断棋盘某处位置是否为空的函数,参数为该点坐标
{
if (a[b - 1][c - 1] == ' ') //(b,c)为坐标,b-1,c-1为数组元素的下标
return 1; //该处为空,可以下棋子
else
return 0; //该处有棋子,不可下
}
void computer_move(int a[ROW][COL], int row, int col)
{
int x = 0, y = 0;
srand((unsigned)time(NULL));
while (1)
{
x = rand() % 4; //rand随机生成正整数,%3使生成结果<3
y = rand() % 4;
if (full(a,x,y))
{
a[x-1][y-1] = 'X';
break;
}
}
}
void player_move(int a[ROW][COL], int row, int col)
{
printf("请玩家下棋\n");
int x = 0, y = 0;
while (1)
{
scanf("%d %d", &x, &y);
if (full(a, x, y))
{
a[x-1][y-1] = 'O';
break;
}
else
{
printf("输入错误,请重新输入!");
}
}
}
int who_win(int a[ROW][COL], int row, int col)
{
//一种情况,棋盘未满,但有一方已连成一条线三个,每次下完都要扫描
//判断一行是否全部相同,一个想法,是否可以用循环来比较两元素值是否相等
int i = 0;
int j = 0;
int countO = 0;
int countX = 0;
//判断对角线
for (i = 0; i < row; i++)
{
j = i;
if (a[i][j] == 'O')
{
countO++;
}
else if (a[i][j] == 'X')
{
countX++;
}
}
if (countO == row)
{
printf("duijiao玩家赢!恭喜你!\n");
return 1;
}
else if (countX == row)
{
printf("很遗憾,电脑赢了,你真的是菜鸡\n");
return 1;
}
//判断反对角线
countO = 0;
countX = 0;
for (i = 0; i < row; i++)
{
j = col-1-i;
if (a[i][j] == 'O')
{
countO++;
}
else if (a[i][j] == 'X')
{
countX++;
}
}
if (countO == row)
{
printf("duijiao玩家赢!恭喜你!\n");
return 1;
}
else if (countX == row)
{
printf("很遗憾,电脑赢了,你真的是菜鸡\n");
return 1;
}
//判断行
for (i = 0; i < row; i++)
{
countO = 0;
countX = 0;
for (j = 0; j < col; j++)
{
if (a[i][j] == 'O')
{
countO++;
}
else if (a[i][j] == 'X') //只要一行里有一个数不满足跟同行其他数相等就没赢,跳出,无需再判断
{
countX++;
}//想到一个问题,通过判断整列是否全为某个元素来判是否有一方获胜,目前这种写法只能写出3*3格为三子棋,4*4格为四子棋,无法做到例如10*10格中下五子棋
}
if (countO == col)
{
printf("hang玩家赢!恭喜你!\n");
return 1;
}
else if (countX == col)
{
printf("很遗憾,电脑赢了,你真的是菜鸡\n");
return 1;
}
}
//判断一列是否全部相同,一个想法,是否可以用循环来比较两元素值是否相等
for (j = 0; j < col; j++)
{
countO = 0;
countX = 0;
for (i = 0; i < row; i++)
{
if (a[i][j] == 'O')
{
countO++;
}
if (a[i][j] == 'X') //只要一列里有一个数不满足跟同行其他数相等就没赢,跳出,无需再判断
{
countX++;
}
//想到一个问题,通过判断整列是否全为某个元素来判是否有一方获胜,目前这种写法只能写出3*3格为三子棋,4*4格为四子棋,无法做到例如10*10格中下五子棋
}
if (countO == row )
{
printf("lie玩家赢!恭喜你!\n");
return 1;
}
else if (countX == row )
{
printf("很遗憾,电脑赢了,你真的是菜鸡\n");
return 1;
}
}
//棋盘已满,胜负未分,没有一方连成了一条,判平局
int num = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if((a[i][j]=='O')||(a[i][j] == 'X') )//full函数前面定义为空返回1,不空返回0
num++;
}
}
if (num == row*col)
{
printf("平局\n");
}
return 0;
}
//test.c
#include "game.h"
void menu () // 写一个菜单
{
printf("————————————\n");
printf("| 1.play |\n");
printf("| 0.exit |\n");
printf("————————————\n");
}
void get_panduan() //接收一个数字,判断是否开始玩游戏
{
int a;
scanf("%d",&a);
switch (a)
{
case 1:
printf("开始游戏\n");
break;
case 0:
printf("游戏已退出\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}
int main()
{
int c[ROW][COL] = { 0 };
int row = ROW;
int col = COL;
int sz = sizeof(c) / sizeof(c[0]);
menu(); //打印菜单
get_panduan(); //判断是否进入游戏
empty(c,row,col); //数组致空格 //打印初始空棋盘 //开始下棋,玩家先走
dayin(c,row,col);
while (1)
{
player_move(c, row, col);
dayin(c, row, col);
if (who_win(c, row, col))
{
break;
}
computer_move(c, row, col);
dayin(c, row, col);
if (who_win(c, row, col))
{
break;
}
}
system("pause");
return 0;
}
让电脑变聪明,后续….