【无标题】三子棋(c语言)可进行棋盘扩增

wuchangjian2021-11-19 01:44:52编程学习

    前言

此程序可进行棋盘扩展,实验结果将进行”5*5棋盘_连4棋赢“状态下的运行结果进行展示,可在game.h头文件对ROW和COL这两个宏进行行列数的随意更改,同样也可对”WIN“宏进行更改,实现连n子赢.


    涉及文件

  • test.c 代码的测试入口
  • game.c 三子棋游戏实现涉及的功能函数
  • game.h 进行函数声明,头文件引用,宏定义变量

    基本实现逻辑:

  • 棋盘初始化
  • 打印棋盘
  • 玩家下棋
  • 判断输赢
  • 电脑下棋
  • 判断输赢


    代码总览:

      game.h 头文件

  • #pragma once
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    
    #define ROW 3
    #define COL 3
    #define WIN 3
    
    //初始化棋盘
    void InitBoard(char board[ROW][COL], int row, int col);
    
    //打印棋盘
    void DisplayBoard(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);
    
    
    //判断输赢
    //玩家赢——'*'
    //电脑赢--'#'
    //平局--'Q'
    //继续--'C'
    char is_win(char board[ROW][COL], int row, int col);

    test.c源文件

  • #define _CRT_SECURE_NO_WARNINGS 1
    
    #include"game.h"
    
    void menu()
    {
    	printf("************************\n");
    	printf("********  1.play  ******\n");
    	printf("********  2.exit  ******\n");
    	printf("************************\n");
    }
    
    
    void game()
    {
    	char board[ROW][COL] = { 0 };
    	InitBoard(board, ROW, COL);//初始化棋盘
    	DisplayBoard(board, ROW, COL);//打印棋盘
    	char ret = 0;
    	while (1)
    	{
    		//玩家下棋
    		player_move(board,ROW,COL);
    		DisplayBoard(board, ROW, COL);
    		ret = is_win(board, ROW, COL);
    		if (ret != 'C')
    		{
    			break;
    		}
    		//电脑下棋
    		computer_move(board,ROW,COL);
    		DisplayBoard(board, ROW, COL);
    		ret = is_win(board, ROW, COL);
    		if (ret != 'C')
    		{
    			break;
    		}
    	}
    	if (ret == '*')
    	{
    		printf("玩家赢了");
    	}
    	else if (ret == '#')
    	{
    		printf("电脑赢了");
    	}
    	else
    	{
    		printf("打平了");
    	}
    }
    
    
    
    void test()
    {
    	int input = 0;
    	srand((unsigned int)time(NULL));
    	do
    	{
    		menu();
    		printf("请输入:>");
    		scanf("%d", &input);
    		switch (input)
    		{
    		case 1:
    			game();
    			break;
    		case 0:
    			printf("退出游戏\n");
    			break;
    		default:
    			printf("选择错误\n");
    			break;
    		}
    	} while (input);
    }
    
    
    int main()
    {
    	test();
    	return 0;
    }
    

    game.c源文件

  • #define _CRT_SECURE_NO_WARNINGS 1
    
    #include"game.h"
    
    
    void InitBoard(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++)
    		{
    			board[i][j] = ' ';
    		}
    	}
    }
    
    void DisplayBoard(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("|");
    			}
    		}
    		printf("\n");
    	}
    }
    
    
    void player_move(char board[ROW][COL], int row, int col)
    {
    	printf("玩家输入:>");
    	int x = 0;
    	int y = 0;
    	
    	while (1)
    	{
    		scanf("%d %d", &x, &y);
    		if (x >= 1 && x <= col && y >= 1 && y <= col)
    		{
    			if (board[x - 1][y - 1] == ' ')
    			{
    				board[x - 1][y - 1] = '*';
    				break;
    			}
    			else
    			{
    				printf("该坐标已被占用,请重新输入!\n");
    			}
    		}
    		else
    		{
    			printf("坐标非法\n");
    		}
    	}
    }
    
    
    void computer_move(char board[ROW][COL], int row, int col)
    {
    	printf("电脑下棋:>\n");
    	int x = 0;
    	int y = 0;
    
    	while (1)
    	{
    		x = rand() % ROW;//0~2
    		y = rand() % COL;//0~2
    		if (board[x][y] == ' ')
    		{
    			board[x][y] = '#';
    			break;
    		}
    	}
    }
    
    
    int is_full(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++)
    		{
    			if (board[i][j] == ' ')
    			{
    				return 0;
    			}
    		}
    	}
    	return 1;
    }
    
    
    char is_win(char board[ROW][COL], int row, int col)
    {
    	int i = 0;
    	int j = 0;
    	int count = 0;
    	//行相同
    	for (i = 0; i < row; i++, count = 0)
    	{
    		for (j = 0; j < col - 1; j++)
    		{
    			if (board[i][j] == board[i][j + 1] && board[i][j] != ' ')
    			{
    				count++;
    			}
    			if (count == WIN-1)
    			{
    				return board[i][j];
    			}
    		}
    	}
    	//列相同
    	for (j = 0; j < col; j++, count = 0)
    	{
    		for (i = 0; i < row - 1; i++)
    		{
    			if (board[i][j] == board[i+1][j] && board[i][j] != ' ')
    			{
    				count++;
    			}
    			if (count == WIN - 1)
    			{
    				return board[i][j];
    			}
    		}
    	}
    	//斜向相同
    	//向下循环
    	int count1 = 0;
    	for (i = 0; i < row; i -= (count1 - 1), count1 = 0, count = 0)//count1:消除内部循环对外部i的影响
    	{
    		for (j = 0; i < row - 1 && j < col - 1; i++, j++)
    		{
    			if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ')
    			{
    				count++;
    			}
    			if (count == WIN - 1)
    			{
    				return board[i][j];
    			}
    			count1++;
    		}
    	}
    	count1 = 0;
    	//斜向相同
    	//向上循环
    	for (j = 0; j < col - WIN + 1; j -= (count1 - 1), count1 = 0, count = 0)//count1:消除内部循环对外部i的影响
    	{
    		for (i = 0; i < row - 1 && j < col - 1; i++, j++)
    		{
    			if ((board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ')||                        //右下方向
    				(board[i][col - 1 - j] == board[i + 1][col - 2-j] && board[i][col - 1 - j] != ' ')) //左下方向
    			{
    				count++;
    			}
    			if (count == WIN - 1)
    			{
    				return board[i][j];
    			}
    			count1++;
    		}
    	}
    
    
    	//平局
    	if (1 == is_full(board, row, col))
    	{
    		return 'Q';
    	}
    
    	//继续
    	return 'C';
    }
    
    
    
    
    

    实验结果:

  • 键盘初始化

  • 成功界面

  • 棋盘扩展后状态(5*5棋盘_连4棋赢)

 

 


     总结

  • 程序为提高扩展性,便于后期维护,采用宏定义变量的方式对棋盘大小进行定义,进而有了”打印棋盘“过程,”判断输赢“过程中多次循环的出现,对其进行适应。虽然电脑下棋可谓人工智障,但还是有许多可借鉴之处的。

相关文章

mysql中find_in_set()函数

注意:mysql字符串函数 find_in_set(str1,str2)函...

值类型与引用类型

一个类型要么是值类型,要么是引用类型。 区别在于拷贝方式...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。