简单井字棋设计

发布于:2023-02-02 ⋅ 阅读:(400) ⋅ 点赞:(0)

 前言:

      大家好,欢迎阅读简单井字棋设计,本片适合初学者阅读与学习,所以程序并没有那麽复杂。

      首先介绍一下井字棋规则:在3*3的9宫格内自己的三个棋子连成一条直线为胜利。


前期准备:

      首先我们需要创建两个源文件和一个头文件,如下图所示

首先我们规定test.c :

                                 用于游戏开始时菜单的打印;

                                 开始游戏和退出游戏的操作,以及循环游玩游戏的操作;

                                 游戏主体如何调用函数;

game.c主要负责:

                              游戏开始菜单的实现;

                              数组的初始化;

                              棋盘的打印;

                              玩家下棋;

                              电脑下棋;

                              输赢的判断;

game.h主要负责:

                              行号、列好;

                              函数的声明;

                              库函数的包含;


程序的实现:

gitee链接:井字棋(csdn版) · 风夏/c语言初级学习 - 码云 - 开源中国 (gitee.com)

test.c(并不完整)

开始时我们只需要书写能想到的步骤即可,不需要开始时文件写的就特别完整,后续需要时我们在往里面添加。

#define  _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void game()
{
	//创建数组,存放变量
	char board[ROW][COL] = { 0 };
	//用于判断胜利
	char ret = '0';
	

	//初始化数组内容,和打印棋盘
	init_board(board, ROW, COL);
	printf_board(board, ROW, COL);

	//玩家下棋和电脑下棋
	player_move(board, ROW, COL);
	ret=is_win(board, ROW, COL);
	computer_move(board, ROW, COL);
	ret=is_win(board, ROW, COL);
}

int main()
{
	//用input来接收变量,判断是否开始游戏
	int input = 0;
	//此处设置随机值,让电脑随机下棋
	srand((unsigned int)time(NULL));
	do
	{
		printf("请选择:\n");
		//打印开始菜单
		menu();
		scanf("%d ", &input);
		switch (input)
		{
		case 0:
			printf("已退出游戏!\n");
			break;
		case 1:
			printf("开始游戏\n");
			game();
			break;
		default:
			printf("输入错误,请重新输入:\n");
			break;
		}
	}
	while (input);
	
	return 0;

}

game.c文件(完整版)

#define  _CRT_SECURE_NO_WARNINGS 1

#include "game.h"


//打印菜单的实现
void menu()
{
	printf("******************************************\n");
	printf("************   1 . 开始游戏   ************\n");
	printf("************   0 . 退出游戏   ************\n");
	printf("******************************************\n");
}

//初始化函数的实现
void init_board(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 printf_board(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{   
		//打印带有符号的行
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		//打印分割行
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("___");
				if (j < col - 1)
					printf("|");
			}
		}
		//到了最后一行为了保持对称和美观只打印了‘|’
		else
		{
			for (j = 0; j < col; j++)
			{
				printf("   ");
				if (j < col -1 )
					printf("|");
			}
			
		}
		printf("\n");
	}
}

//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	do 
	{
		do
		{
			printf("请输入坐标:\n");
			scanf("%d %d", &x, &y);
			if (x > 0 && x <= row && y > 0 && y <= col)
				break;
			else
				printf("输入坐标错误,请重新输入:\n");
		} while (1);
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '*';
			break;
		}
		else
		{
			printf("输入坐标已被占用,请重新输入:\n");
		}
	} while (1);
	printf_board(board, row, col);
}

//电脑随机下棋
void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	do 
	{
		x = rand() % row;
	    y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	} while (1);
	printf_board(board, row, col);
}

//判断胜负
//*代表玩家胜
//#代表电脑胜
//Q平局C继续
char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//判断行胜利
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][0]!=' ')
			return board[i][0];
	}
	//判断列胜利
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	//判断对角线胜利
	if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') || (board[0][2] == board[1][1] && board[1][1] == board[2][0]) && board[1][1] != ' ')
		return board[1][1];
	//判断平局或继续
	for (i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			if (board[i][j] == ' ')
				return 'C';

	}
	return 'Q';
}

注释:is_win的返回值

//*代表玩家胜
//#代表电脑胜
//Q平局C继续


这时候可以返回来,完成我们text.c文件(完整版)

#define  _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void game()
{
	//创建数组,存放变量
	char board[ROW][COL] = { 0 };
	//用于判断胜利
	char ret = '0';
	

	//初始化数组内容,和打印棋盘
	init_board(board, ROW, COL);
	printf_board(board, ROW, COL);

	//玩家下棋和电脑下棋
	do
	{
		player_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
		computer_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	} while (1);
	//输出结果
	if (ret == '*')
	{
		printf("玩家胜\n");
	}
	else if(ret=='#')
	{
		printf("电脑胜\n");
	}
	else
	{
		printf("平局\n");
	}
}

int main()
{
	//用input来接收变量,判断是否开始游戏
	int input = 0;
	//此处设置随机值,让电脑随机下棋
	srand((unsigned int)time(NULL));
	do
	{
		//打印开始菜单
		menu();
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			printf("已退出游戏!\n");
			break;
		case 1:
			printf("开始游戏\n");
			game();
			break;
		default:
			printf("输入错误,请重新输入:\n");
			break;
		}
	}
	while (input);
	
	return 0;

}

最后我们可以完整一下game.h文件(完整版)

#pragma once

//库函数的包含
//引用了输入输出函数
#include<stdio.h>
//引用随机变量
#include<stdlib.h>
//引用时间戳
#include<time.h>


#define ROW 3
#define COL 3


//函数的声明,要用分号
void init_board(char board[ROW][COL], int row, int col);
void printf_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);




总结:

      三子棋的逻辑并没有特别复杂,非常适合初学者。初学者要保持良好的心态,自己动手尝试写出来。

      首先我们要明白、了解三子棋的最基本思路

      然后逐步完成每个文件,并不需要一次性写的非常完整,到程序需要的时候在往上面补充,也是个不错的选择。

      最后每完成一个步骤,我们能对他进行调试,以保证正确性,除非是计算机大神就当我没说过。



  完结:

        希望大家越学越好哦!!!

        下一次,我将在此次的基础上添加智能拦截,智能获胜功能,敬请期待。。。。。。