使用c语言实现三子棋
一、思路
1.游戏开始界面和棋盘需要打印在屏幕上,界面用printf函数,棋盘使用两层循环,空白处使用空格。注意下划线和竖线的打印次数。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include"stdio.h"
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<stdbool.h>
#include<limits.h>
#define ROW 3//行数
#define COL 3//列数
void initboard(char board[ROW][COL], int row, int col);
void printboard(char board[ROW][COL], int row, int col);
void player(char board[ROW][COL], int row, int col);
void computer(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);
void menu()
{
while (true)
{
printf("******************\n");
printf(" 选择1开始游戏 \n");
printf(" 选择0结束游戏 \n");
printf("******************\n");
int n;
printf("请输入\n");
scanf("%d", &n);
if (n == 1)
{
printf("开始游戏\n");
game();
}
else if (n == 0)
{
printf("结束游戏\n");
break;
}
else
{
printf("输入错误,请重新输入\n");
}
}
}
void initboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++) {
board[i][j] = ' ';
}
}
}
void printboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf("%c", board[i][j]);
if (j < col - 1) {
printf("|");
}
}
printf("\n");
if (i < row - 1) {
for (int k = 0; k < col; k++) {
printf("--");
}
}
printf("\n");
}
}
2.玩家下棋的字符这里使用'#',电脑下棋使用'*' 。玩家下棋需要考虑坐标已被占用(重复)和坐标非法(数组越界),使用if语句判断 if (board[x - 1][y - 1] == '#' ||board[x - 1][y - 1] == '*' ),else if (x > row || x<0 || y>col || y < 0),并且输入坐标从1开始,数组从0开始,需要调整。电脑下棋使用随机数的方法,rand(),srand(time(NULL)),头文件<time.h>,随机数种子使用时间戳,时间戳会不停的变化,并且也要考虑坐标已被占用(重复),而越界不会,随机数限定范围。
int main()
{
srand((unsigned int)time(NULL));
menu();
return 0;
}
void player(char board[ROW][COL], int row, int col)
{
printf("请输入下棋的坐标\n");
while (true)
{
int x, y;
scanf("%d %d", &x, &y);
if (board[x - 1][y - 1] == '#' ||board[x - 1][y - 1] == '*' )
{
printf("坐标被占用,请重新输入\n");
}
else if (x > row || x<0 || y>col || y < 0)
{
printf("坐标非法,请重新输入\n");
}
else {
board[x - 1][y - 1] = '#';
break;
}
}
printf("玩家下棋\n");
}
void computer(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
while (true)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] != '*' && board[x][y] != '#') {
board[x][y] = '*';
break;
}
}
}
3.胜负判定,三个相同即为胜利,分为一行3个,一列3个,主对角线(左上到右下),副对角线(右上到左下),考虑边界,两层循环,x,y都会变化。
(1)一行:(x,y-1) (x,y) (x,y+1),1<x<col,1<y<row-1
(2)一列:(x-1,y) (x,y) (x+1,y),1<x<col-1,1<y<row
(3)主对角线:(x-1,y-1) (x,y) (x+1,y+1),1<x<col-1,1<y<row-1
(4)副对角线:(x+1,y-1) (x,y) (x-1,y+1),1<x<col-1,1<y<row-1
返回值
玩家赢 ’#‘
电脑赢 '*'
平局 'q'
继续游戏 'c'
char is_win(char board[ROW][COL], int row, int col)
{
//一行
for (int y = 1; y < col - 1; y++) {
for (int x = 0; x < row; x++) {
if (board[x][y - 1] == board[x][y] && board[x][y] == board[x][y + 1] && board[x][y] != ' ')
{
return board[x][y];
}
}
}
//一列
for (int x = 1; x < row - 1; x++) {
for (int y = 0; y < col; y++) {
if (board[x - 1][y] == board[x][y] && board[x][y] == board[x + 1][y] && board[x][y] != ' ')
{
return board[x][y];
}
}
}
//主对角线
for (int x = 1; x < row - 1; x++) {
for (int y = 1; y < col - 1; y++)
{
if (board[x - 1][y - 1] == board[x][y] && board[x][y] == board[x + 1][y + 1] && board[x][y] != ' ')
{
return board[x][y];
}
}
}
//副对角线
for (int x = 1; x < row - 1; x++) {
for (int y = 1; y < col - 1; y++)
{
if (board[x + 1][y - 1] == board[x][y] && board[x][y] == board[x - 1][y + 1] && board[x][y] != ' ')
{
return board[x][y];
}
}
}
for (int x = 0; x < row; x++)
{
for (int y = 0; y < col; y++)
{
if (board[x][y] == ' ') {
return 'c';
}
}
}
//平局
return 'q';
}
游戏函数的实现代码
void game()
{
char board[ROW][COL];
initboard(board, ROW, COL);
printboard(board, ROW, COL);
while (1) {
player(board, ROW, COL);
printboard(board, ROW, COL);
if (is_win(board, ROW, COL) != 'c')
{
break;
}
computer(board, ROW, COL);
printboard(board, ROW, COL);
if (is_win(board, ROW, COL)!='c')
{
break;
}
}
if (is_win(board, ROW, COL)=='#') {
printf("玩家赢\n");
}
else if (is_win(board, ROW, COL) == '*') {
printf("电脑赢\n");
}
else {
printf("平局\n");
}
}
这是三子棋的代码实现,在以后的学习路上会分享更多的代码和实现思路,总结更多的知识,不断努力。