栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

N子棋的实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

N子棋的实现

目录
  1. 前言
  2. 一、游戏的实现完成界面
  3. 二、游戏的实现
    1. 声明:
    2. 所用的库
    3. 所用的函数
  4. 三、全部代码

前言

本文章主要介绍N子棋的实现。


一、游戏的实现完成界面

1.首先会出现一个菜单,让玩家来选择开始游戏或者退出游戏

 2.开始游戏后,玩家可以选择自己想要的棋盘规格

 例如玩家想要4x4的棋盘,则可以输入:4 4,然后就会打印出棋盘

 3.玩家可以选择电脑先下或者自己先下,这里选择自己先下

4.然后就是玩家下子,玩家下完后,会重新打印一次棋盘,显示玩家下完后的棋盘,并且电脑也一样。

 5.玩家赢/电脑赢/平局


二、游戏的实现 1.声明:

本代码将 board[i][j] 用以下形式来代表
board[i*col+j]

原因:见二维数组的多种定义法及作为函数参数的使用方法_Wwerday的博客-CSDN博客
这样的话,传参时就可以直接传baord的地址,引用时,就可以采用 board[i*col+j] 的方法,其中,col代表二维数组的列,这样的话就可以实现让玩家选择棋盘的规格

2.所用的库
#include 
#include 
#include 
3.所用的函数
void meau();
void game();
void Initboard(char* board, int row, int col);
void Printboard(char* board, int row, int col);
void PlayerMove(char* board, int row, int col);
void ComputerMove(char* board, int row, int col);
char Iswin(char* board, int row, int col);

1.meau()

void meau()
{
	printf("*********************************n");
	printf("*********************************n");
	printf("********* 1.start  0.exit *******n");
	printf("*********************************n");
	printf("*********************************n");
}

2.Initboard() // 初始化棋盘

void Initboard(char *board, int row, int col)
{
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			board[i*col+j] = ' ';
		}
	}
}

3.Printboard() // 打印棋盘 

   |   |   
---|---|---
   |   |   
---|---|---
   |   |
void Printboard(char *board, int row, int col)
{
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			printf(" %c ", board[i * col + j]);
			if (j < col - 1)
				printf("|");
		}
		printf("n");
		if (i < row - 1) {
			for (int j = 0; j < col; j++) {
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("n");
		}

	}
}

4.PlayerMove() // 玩家落子

void PlayerMove(char *board, int row, int col)
{
	while (1) {
		int x, y;
		printf("请输入你要下的位置>:");
		scanf("%d %d", &x, &y);
		if (board[(x-1)*col + (y-1)] != ' ') {
			printf("该位置已经有棋子了!n");
		}
		else if (x > row || x < 0 || y > col || y < 0) {
			printf("输入有误,请重新输入!n");
		}
		else {
			printf("玩家下:n");
			board[(x - 1) * col + (y - 1)] = '*';
			break;
		}
	}
}

 5.ComputerMove() // 电脑落子

//电脑落子
//其实可以用枚举的方式实现电脑智能落子的,但是我只能想到这种方法实现,觉得这种方法太笨了,要写很多而且没什么意义,
//所以就只是让电脑随机落子了。
//期待有更好的方法

void ComputerMove(char *board, int row, int col)
{
	int x, y;
	
	printf("电脑下:n");
	while (1) {
		x = rand() % row;
		y = rand() % col;
		if (board[x * col + y] == ' ') {
			board[x * col + y] = '#';
			break;
		}
	}
}

6. Iswin() // 判断棋盘的情况

//返回‘*’代表玩家赢
//返回‘#’代表电脑赢
//返回‘Q’代表平局
//返回‘C’代表继续

char Iswin(char *board, int row, int col)
{
	//行检查
	int i, j;
	for (i = 0; i < row; i++) {
		char ch = board[i * col + 0];
		if (ch == ' ')
			break;
		int flag = 0;
		for (j = 1; j < col; j++) {
			if (ch != board[i * col + j]) {
				flag = 1;
				break;
			}
		}
		//注意:假如flag仍然为0,则j出循环的时候等于col,所以此处j-1.
		if (flag == 0)
			return ch;
	}

	//列检查
	for (i = 0; i < col; i++) {
		char ch = board[i * col + 0];
		if (ch == ' ')
			break;
		int flag = 0;
		for (j = 1; j < row; j++) {
			if (ch != board[j * col + i]) {
				flag = 1;
				break;
			}
		}
		if (flag == 0)
			return ch;
	}

	//对角线
	int flag1 = 0;
	char c;
	for (i = 1, j = 1; i < row && j < col; i++, j++) {
		c = board[0 * col + 0];
		if (board[i * col + j] != c) {
			flag1 = 1;
			break;
		}
	}
	//对角线判断和行列不同,假如按照前面的方法,对角线上有空格的话,会直接返回空格
	if (flag1 == 0 && c != ' ')
		return c;

	int flag2 = 0;
	for (i = 1, j = col - 2; i < row && j >= 0; i++, j--) {
		c = board[0 * col + col - 1];
		if (board[i * col + j] != c) {
			flag2 = 1;
			break;
		}
	}
	if (flag2 == 0 && c != ' ')
		return c;

	//判断是否继续
	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			if (board[i * col + j] == ' ')
				return 'C';
		}
	}

	//以上都不满足,则是平局
	return 'Q';
}

 7.game() // 游戏的整体逻辑

void game()
{
	int ROW, COL;
	printf("请输入棋盘规格(如 3*3 输入:3 3):");
	scanf("%d%d", &ROW, &COL);
	
	char* board = (char*)malloc(ROW * COL * sizeof(char));
	Initboard(board, ROW, COL);
	Printboard(board, ROW, COL);

	printf("选择你先下/电脑先下(1/0)n");
	int ret;
	scanf("%d", &ret);
	while (1) {
		if (ret == 1) {
			PlayerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
			ComputerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
		}
		else if (ret == 0) {
			ComputerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
			PlayerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
		}
		else {
			printf("输入有误,请重新输入。n");
		}
	}
	char ch = Iswin(board, ROW, COL);
	if (ch == '*')
		printf("玩家赢!n");
	else if (ch == '#')
		printf("电脑赢!n");
	else
		printf("平局。n");
}

 三、全部代码

game.h

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
void meau();
void game();
void Initboard(char* board, int row, int col);
void Printboard(char* board, int row, int col);
void PlayerMove(char* board, int row, int col);
void ComputerMove(char* board, int row, int col);
char Iswin(char* board, int row, int col);

game.c 

#include "game.h"

//
// 本代码将 board[i][j] 用以下形式来代表
// board[i*col+j]
// 这样的话,就可以使用让玩家选择棋盘的规格
//

void meau()
{
	printf("*********************************n");
	printf("*********************************n");
	printf("********* 1.start  0.exit *******n");
	printf("*********************************n");
	printf("*********************************n");
}

void game()
{
	int ROW, COL;
	printf("请输入棋盘规格(如 3*3 输入:3 3):");
	scanf("%d%d", &ROW, &COL);
	
	char* board = (char*)malloc(ROW * COL * sizeof(char));
	Initboard(board, ROW, COL);
	Printboard(board, ROW, COL);

	printf("选择你先下/电脑先下(1/0)n");
	int ret;
	scanf("%d", &ret);
	while (1) {
		if (ret == 1) {
			PlayerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
			ComputerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
		}
		else if (ret == 0) {
			ComputerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
			PlayerMove(board, ROW, COL);
			Printboard(board, ROW, COL);
			if (Iswin(board, ROW, COL) != 'C')
				break;
		}
		else {
			printf("输入有误,请重新输入。n");
		}
	}
	char ch = Iswin(board, ROW, COL);
	if (ch == '*')
		printf("玩家赢!n");
	else if (ch == '#')
		printf("电脑赢!n");
	else
		printf("平局。n");
}


//初始化棋盘
void Initboard(char *board, int row, int col)
{
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			board[i*col+j] = ' ';
		}
	}
}
//   |   |   
//---|---|---
//   |   |   
//---|---|---
//   |   |

//打印棋盘
void Printboard(char *board, int row, int col)
{
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			printf(" %c ", board[i * col + j]);
			if (j < col - 1)
				printf("|");
		}
		printf("n");
		if (i < row - 1) {
			for (int j = 0; j < col; j++) {
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("n");
		}

	}
}

//玩家落子
void PlayerMove(char *board, int row, int col)
{
	while (1) {
		int x, y;
		printf("请输入你要下的位置>:");
		scanf("%d %d", &x, &y);
		if (board[(x-1)*col + (y-1)] != ' ') {
			printf("该位置已经有棋子了!n");
		}
		else if (x > row || x < 0 || y > col || y < 0) {
			printf("输入有误,请重新输入!n");
		}
		else {
			printf("玩家下:n");
			board[(x - 1) * col + (y - 1)] = '*';
			break;
		}
	}
}

//电脑落子
//其实可以用枚举的方式实现电脑智能落子的,但是我只能想到这种方法实现,觉得这种方法太笨了,要写很多而且没什么意义,
//所以就只是让电脑随机落子了。
//期待有更好的方法
void ComputerMove(char *board, int row, int col)
{
	int x, y;
	
	printf("电脑下:n");
	while (1) {
		x = rand() % row;
		y = rand() % col;
		if (board[x * col + y] == ' ') {
			board[x * col + y] = '#';
			break;
		}
	}
}

//返回‘*’代表玩家赢
//返回‘#’代表电脑赢
//返回‘Q’代表平局
//返回‘C’代表继续
char Iswin(char *board, int row, int col)
{
	//行检查
	int i, j;
	for (i = 0; i < row; i++) {
		char ch = board[i * col + 0];
		if (ch == ' ')
			break;
		int flag = 0;
		for (j = 1; j < col; j++) {
			if (ch != board[i * col + j]) {
				flag = 1;
				break;
			}
		}
		//注意:假如flag仍然为0,则j出循环的时候等于col,所以此处j-1.
		if (flag == 0)
			return ch;
	}

	//列检查
	for (i = 0; i < col; i++) {
		char ch = board[i * col + 0];
		if (ch == ' ')
			break;
		int flag = 0;
		for (j = 1; j < row; j++) {
			if (ch != board[j * col + i]) {
				flag = 1;
				break;
			}
		}
		if (flag == 0)
			return ch;
	}

	//对角线
	int flag1 = 0;
	char c;
	for (i = 1, j = 1; i < row && j < col; i++, j++) {
		c = board[0 * col + 0];
		if (board[i * col + j] != c) {
			flag1 = 1;
			break;
		}
	}
	//对角线判断和行列不同,假如按照前面的方法,对角线上有空格的话,会直接返回空格
	if (flag1 == 0 && c != ' ')
		return c;

	int flag2 = 0;
	for (i = 1, j = col - 2; i < row && j >= 0; i++, j--) {
		c = board[0 * col + col - 1];
		if (board[i * col + j] != c) {
			flag2 = 1;
			break;
		}
	}
	if (flag2 == 0 && c != ' ')
		return c;

	//判断是否继续
	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			if (board[i * col + j] == ' ')
				return 'C';
		}
	}

	//以上都不满足,则是平局
	return 'Q';
}

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

int main()
{
    int input = 1;
    srand((unsigned int)time(NULL));

    while (1) {
        meau();
        printf("请输入>:");
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            return 0;
        case 1:
            game();
            break;
        default:
            printf("输入有误,请重新输入。n");
        }
    }
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021995.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号