C语言小游戏--三子棋

C语言小游戏–三子棋


  三子棋是一种传统民间的小游戏,(别名圈圈叉叉,井字格棋)只需要一个井字格便可以快速玩一把,任一方只要三棋子连成一条线就算胜利。作为简单轻松的小游戏,相信不少人都玩过,我也在小学初中上课时和同桌没少玩。
在这里插入图片描述

			三子棋 (图片来自百度)

   而C语言也可以实现简单三子棋游戏,并和电脑做对手进行人机对战。设计思路如下:

设计思路

  1. 先展示游戏菜单利用swtich语句通过用户输入进行选择,具体操作代码如下。
void Menu()       //菜单函数
{
	printf(" _________________________________\n");
	printf(" |                               |\n");
	printf(" |           1.开始游戏          |\n");
	printf(" |           0. 退 出            |\n");
	printf(" ---------------------------------\n");
}

int main()      
{
	int select = 0;
	int quit = 0;
	while (!quit){
		printf("要来一把三子棋吗?\n");
		Menu();
		scanf("%d", &select);
		switch (select){
			case 1:
				Game();
				break;
			case 0:
				quit = 1;
				break;
			default:
				printf("请输入正确的选择\n\n");
				break;
		}
	}
	printf("再见!\n");

结果图:
在这里插入图片描述

  1. 需要一个棋盘(3*3)来保存用户和电脑落子。定义一个二维数组(char board[3][3])里面存放落子坐标未落子除保存空格。先将棋盘初始化为空格(InitBoard())然后进行显示。
    在这里插入图片描述
#define INIT ' '     //棋盘初始化为空格
//棋盘初始化函数
static void InitBoard(char board[][COL],int row,int col)
{
	for (int i = 0; i < ROW; i++){
		for (int j = 0; j < COL; j++)
			board[i][j] = INIT;
	}
}
//显示棋盘
static void Show(char board[][COL], int row, int col)
{
	system("cls");system("cls");      // system函数代表执行系统命令,system("cls")就是执行命令“清屏”的意思
	for (int i = 0; i < COL; i++){
		printf("   %d ", i+1);
	}
	printf("\n    ____________\n");
	for (int i = 0; i < ROW; i++){
		printf("%d  ", i+1);
		for (int j = 0; j < COL; j++){
			printf(" |%c ",board[i][j]);
		}
		printf("\n    ------------\n");
	}
}

结果图:
在这里插入图片描述

  1. 之后便进入了代码最核心也是游戏主要的功能**Game()**函数,将各个功能和流程架构组织起来,整个游戏开始和结束都在Game中进行。
#define ROW  3       //棋盘大小三行
#define COL  3       //棋盘大小三列
#define PLAYER      'O'    //玩家棋子为O 
#define COMPUTER   'X'   //电脑棋子为X
#define DRAW 'D'       //平局
#define NEXT 'N'       //继续

void Game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);				//初始化棋盘
	srand((unsigned long)time (NULL));         //随机数种子
	char result = 0;
	while (1){
		Show(board, ROW, COL);    
		//  玩家落子  
		Player(board, ROW, COL);
		result = End(board, ROW, COL);       //判断结果
		if (result != NEXT){
			break;
		}
		Show(board, ROW, COL);
		//  电脑落子
		Computer(board, ROW, COL);
		result = End(board, ROW, COL);
		if (result != NEXT){
			break;
		}
		
	}
	switch (result){    //result带来的三种最终结果
		case PLAYER:
			printf("你赢了!!!\n\n\n");
			break;
		case COMPUTER:
			printf("Game Over,你输给了电脑。\n\n\n");
			break;
		case DRAW:
			printf("你和电脑下了个平手。\n\n\n");
			break;
		default :
			printf("BUG????\n\n");      //不应该运行到这
			break;
	}
}

部分游戏结果:
在这里插入图片描述

  1. 玩家和电脑的落子也是重要的一环,玩家落子(Player())通过键盘输入坐标选定落子位置下’O’,电脑(Computer())通过循环生成随机数坐标传入落子位置(因为棋盘较小可以用随机数较为简单的解决)。
    这里注意要进行对落子位置判断是否合法以及是否已经有落子,即只有输入坐标 == 空格时才成功落子否则重新输入落子坐标。
static void Player(char board[][COL], int row, int col)
{   
	int x, y;
	x = 0, y = 0;
	while (1){
		printf("请输入你想要下的棋子坐标(x,y)\n");
		scanf("%d %d", &x, &y);
		if (x<ROW - 2 || y<COL - 2 || x>ROW || y>COL){
			printf("请输入正确的坐标\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT){
			board[x - 1][y - 1] = PLAYER;
			break;
		}
		else{ printf("这个位置已经有棋子了\n"); 
		}
	}

}

 void Computer(char board[][COL], int row, int col)
{   
	while (1){
		int x = rand() % ROW;
		int y = rand() % COL;
		if (board[x][y] == INIT){
			board[x][y] = COMPUTER;
			break;
		}
	}
	
}


  1. 在落子之后需要判断有没有出现结果,**End()**函数。在游戏进行中我们应考虑四种结果,玩家(Player)胜利,电脑(Computer)胜利,平局(DRAW),以及没人胜利切还有落子位置还需继续(NEXT)落子。
    通过枚举遍历的方式简单直观的完成了对每个位置的检索。
static char End(char board[][COL], int row, int col)
{	
	for (int i = 0; i < ROW; i++){
		if (board[i][0] == board[i][1] && \
			board[i][1] == board[i][2] && \
			board[i][1] != INIT){
			return board[i][1];
		}
	}

	for (int j = 0; j < COL; j++){
		if (board[0][j] == board[1][j] && \
			board[1][j] == board[2][j] && \
			board[1][j] != INIT){
			return board[1][j];
		}
	}
	if (board[0][2] == board[1][1] && \
		board[1][1] == board[2][0] && \
		board[1][1] != INIT){
		return board[1][1];
	}
	if (board[0][0] == board[1][1] && \
		board[1][1] == board[2][2] && \
		board[1][1] != INIT){
		return board[1][1];
	}
	for (int i = 0; i < ROW; i++){
		for (int j = 0; j < COL; j++)
		if (board[i][j]==INIT){
			return NEXT;
		}
	}
	return DRAW;
	
}

结果图:

在这里插入图片描述
在这里插入图片描述

三子棋源代码

头文件

#pragma once

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>        //生成随机数
#include <time.h>          //时间生成随机数种子
#pragma warning (disable:4996)

#define ROW  3       //棋盘大小三行
#define COL  3       //棋盘大小三列
#define INIT ' '     //棋盘初始化为空格
#define DRAW 'D'       //平局
#define NEXT 'N'       //继续
#define PLAYER      'O'    //玩家棋子为O 
#define COMPUTER   'X'   //电脑棋子为X

extern void Menu();
extern void Game();
extern void InitBoard(char board[][COL], int row, int col);
extern void Show(char board[][COL], int row, int col);
extern char End(char board[][COL], int row, int col);
extern void Player(char board[][COL], int row, int col);
extern void Computer(char board[][COL], int row, int col);

主函数

#include "three.h"


int main()
{
	int select = 0;
	int quit = 0;
	while (!quit){
		printf("要来一把三子棋吗?\n");
		Menu();
		scanf("%d", &select);
		switch (select){
			case 1:
				Game();
				break;
			case 0:
				quit = 1;
				break;
			default:
				printf("请输入正确的选择\n\n");
				break;
		}
	}
	printf("再见!\n");
	system("pause");
	return 0;
}

函数主体

#include "three.h"

void Menu()
{
	printf(" _________________________________\n");
	printf(" |                               |\n");
	printf(" |           1.开始游戏          |\n");
	printf(" |           0. 退 出            |\n");
	printf(" ---------------------------------\n");
}

static void InitBoard(char board[][COL],int row,int col)
{
	for (int i = 0; i < ROW; i++){
		for (int j = 0; j < COL; j++)
			board[i][j] = INIT;
	}
}

static void Show(char board[][COL], int row, int col)
{
	system("cls");      // system函数代表执行系统命令,system("cls")就是执行命令“清屏”的意思
	for (int i = 0; i < COL; i++){
		printf("   %d ", i+1);
	}
	printf("\n    ____________\n");
	for (int i = 0; i < ROW; i++){
		printf("%d  ", i+1);
		for (int j = 0; j < COL; j++){
			printf(" |%c ",board[i][j]);
		}
		printf("\n    ------------\n");
	}
}

void Game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);				//初始化棋盘
	srand((unsigned long)time (NULL));         //随机数种子
	char result = 0;
	while (1){
		Show(board, ROW, COL);
		Player(board, ROW, COL);
		result = End(board, ROW, COL);
		if (result != NEXT){
			break;
		}
		Show(board, ROW, COL);
		Computer(board, ROW, COL);
		result = End(board, ROW, COL);
		if (result != NEXT){
			break;
		}
	}
	Show(board, ROW, COL);
	switch (result){
		case PLAYER:
			printf("你赢了!!!\n\n\n");
			break;
		case COMPUTER:
			printf("Game Over,你输给了电脑。\n\n\n");
			break;
		case DRAW:
			printf("你和电脑下了个平手。\n\n\n");
			break;
		default :
			printf("BUG????\n\n");      //不应该运行到这
			break;
	}
}


static char End(char board[][COL], int row, int col)
{	
	for (int i = 0; i < ROW; i++){
		if (board[i][0] == board[i][1] && \
			board[i][1] == board[i][2] && \
			board[i][1] != INIT){
			return board[i][1];
		}
	}

	for (int j = 0; j < COL; j++){
		if (board[0][j] == board[1][j] && \
			board[1][j] == board[2][j] && \
			board[1][j] != INIT){
			return board[1][j];
		}
	}
	if (board[0][2] == board[1][1] && \
		board[1][1] == board[2][0] && \
		board[1][1] != INIT){
		return board[1][1];
	}
	if (board[0][0] == board[1][1] && \
		board[1][1] == board[2][2] && \
		board[1][1] != INIT){
		return board[1][1];
	}
	for (int i = 0; i < ROW; i++){
		for (int j = 0; j < COL; j++)
		if (board[i][j]==INIT){
			return NEXT;
		}
	}
	return DRAW;
	
}


static void Player(char board[][COL], int row, int col)
{   
	int x, y;
	x = 0, y = 0;
	while (1){
		printf("请输入你想要下的棋子坐标(x,y)\n");
		scanf("%d %d", &x, &y);
		if (x<ROW - 2 || y<COL - 2 || x>ROW || y>COL){
			printf("请输入正确的坐标\n");
			continue;
		}
		if (board[x - 1][y - 1] == INIT){
			board[x - 1][y - 1] = PLAYER;
			break;
		}
		else{ printf("这个位置已经有棋子了\n"); 
		}
	}

}

 void Computer(char board[][COL], int row, int col)
{   
	while (1){
		int x = rand() % ROW;
		int y = rand() % COL;
		if (board[x][y] == INIT){
			board[x][y] = COMPUTER;
			break;
		}
	}
	
}




ps:随后我会补充更完整的解决思路。希望大家评论留言

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值