任意子祺

17 篇文章 0 订阅

简介

这个任意子棋向玩家提供任选棋盘大小、任选连珠数量功能。但缺点是电脑太傻只会随机落子、不能用鼠标点击、没有可视化的图形界面。这里的电脑下棋我使用的是随机函数,所以与玩家对战的电脑显得很智障。其实这也是类似于五子棋这一类棋牌游戏的难点所在。想要使电脑聪明,完全可以–人工智能啊深度学习啊什么的,但是明显我不会。在这里我想到了两种使电脑看起来“聪明”的办法,第一种:加上各种if语句来模拟各种情景下电脑应该怎样走–这种方法不是一个聪明的计算机本科生应该做的,pass; 第二种:写一个算法,判断图的连通性,根据图的连通性再权衡进攻或者防守,动态地做出判断–明显这种方法特别复杂,等到以后再写吧。

我所使用的是VS2008, 采用TDD模式,任意子棋程序分为3个源文件,分别是:game.h 、game.c 、index.c

源代码

game.h 文件中放声明, game.c 里放函数的定义, index.c 里放主函数。

index.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include "game.h"
int x=0, y=0;
int main(){
    int level=0, num=0, Pioneer=0;
    char sign='\0';
    char board[ROW][COL];
    int again=0;
    int c=0;
    srand((unsigned int)time(NULL));
AGAIN1: Creat_Rule(&level, &num, &Pioneer);
AGAIN2:  Init_Board(board,level);
     Show_Board(board,level);
     if(Pioneer==1)            //玩家先走
     {
        while(1)
        {
            Player_Do(board,level);
            Show_Board(board,level);
            sign=Judge_Win(board,level, num);
//          printf("sign=%c\n",sign);
            if(sign=='X')
            {
                printf("恭喜你,获胜!!!\n");
                break;
            }
            else if(sign=='q')
            {
                printf("平局!\n");
                break;
            }
            Computer_Do(board,level);
            Show_Board(board,level);
            sign=Judge_Win(board,level, num);
            if(sign=='O')
            {
                printf("很遗憾,电脑胜!!!\n");
                break;
            }
            else if(sign=='q')
            {
                printf("平局!\n");
                break;
            }
        }
     }

     else                                   //电脑先走
     {

         while(1)
         {
             Computer_Do(board,level);
             Show_Board(board,level);
             sign=Judge_Win(board,level, num);
//           printf("sign=%c\n",sign);
             if(sign=='O')
             {
                 printf("恭喜你,获胜!!!\n");
                 break;
             }
             else if(sign=='q')
             {
                 printf("平局!\n");
                 break;
             }
             Player_Do(board,level);
             Show_Board(board,level);
             sign=Judge_Win(board,level, num);
             if(sign=='X')
             {
                 printf("很遗憾,电脑胜!!!\n");
                 break;
             }
             else if(sign=='q')
             {
                 printf("平局!\n");
                 break;
             }
         }
     }
    printf("********************************游戏结束****************************************\n");
    printf("*****不玩了:0********重新开始:1********以当前规则再玩一局:2***************\n");
    scanf("%d", &again);
    while((c = getchar()) != '\n' && c != EOF);
//  if(again!=0) (again==1) ? ( goto AGAIN1) : (goto AGAIN2);
    switch (again)
    {
    case 1: goto AGAIN1; break;
    case 2: goto AGAIN2; break;
    default: return 0;
    }
    return 0;
}

game.h

#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#include<time.h>
#define  ROW 36
#define COL 36
extern int x, y;
void Creat_Rule(int *level, int *num, int *Pioneer);
void Init_Board(char board[ROW][COL], int level);
void Show_Board(char board[ROW][COL], int level);
void Player_Do(char board[ROW][COL], int level);
void Computer_Do(char board[ROW][COL], int level);
char Judge_Win(char board[ROW][COL], int level, int num);
#endif

game.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

extern int x, y;
void Creat_Rule(int *level, int *num, int *Pioneer){
    int c=0;
    char affirm[5]={'\0'};
Loop:
        printf("请选择棋盘大小(3阶到36阶)>");
        while(scanf("%d", level))
        {
            int c=0;
            while((c = getchar()) != '\n' && c != EOF);     //清除键盘缓冲区的万能写法

            if(*level<3) printf("输入错误,请重新指定\n");
            else
            {
                break;
            }   
        }
        printf("您想玩几子连珠?(不得小于3)>");
        while(scanf("%d", num))
        {
            int c=0;
            while((c = getchar()) != '\n' && c != EOF);     //清除键盘缓冲区的万能写法
            if(*num<3) printf("输入错误,请重新输入\n");
            else if(*num>*level)
            {
                printf("超过了棋盘的范围,请重新输入\n");
            }
            else
            {
                break;
            }
        }
        printf("您和电脑谁先走?(若你先走,输入1;若电脑先走,输入2)>");
        while(scanf("%d", Pioneer))
        {
            int c=0;
            while((c = getchar()) != '\n' && c != EOF);     //清除键盘缓冲区的万能写法
            if(*Pioneer!=1 && *Pioneer!=2) printf("输入错误,请重新输入\n");
            else
            {
                break;
            }
        }
        printf("请确认规则:\n");
        if(*Pioneer==1) printf("您定制的规则为: 在一个%d*%d的棋盘上,谁先将%d颗棋子连成一条线谁就赢了,您先走\n", *level, *level, *num);
        else  printf("您定制的规则为: 在一个%d*%d的棋盘上,谁先将%d颗棋子连成一条线谁就赢了,电脑先走\n", *level, *level, *num);
        printf("****************确认并开始游戏?(Y/N)>");
        scanf("%s", affirm);

        while((c = getchar()) != '\n' && c != EOF);     //清除键盘缓冲区的万能写法
        if( !(strcmp(affirm, "Y")==0 || strcmp(affirm, "y")==0 || strcmp(affirm, "YES")==0 || strcmp(affirm, "yes")==0 || strcmp(affirm, "Yes")==0 ) )  goto Loop; 
}

void Init_Board(char board[ROW][COL], int level){
    int i=0, j=0;
    /*board=(char **)malloc(sizeof(char *)*level);
    for (i=0; i<level; i++)
    {
        board[i]=(char *)malloc(sizeof(char *)*level);
    }*/
    for(i=0; i<level; i++)
    {
        for(j=0; j<level; j++)
        {
            board[i][j]=' ';
        }
    }
}
void Show_Board(char board[ROW][COL], int level){
    int i = 0, j = 0;
    for(i=0; i<level; i++)
    {

            for(j=0; j<level; j++)
            {
                printf(" ---");
            }
            printf("\n");
            for (j=0; j<level; j++)
            {
                printf("| %c ",board[i][j]);
            }

            printf("|\n");
        if(i==level-1)
        {
            for(j=0; j<level; j++)
            {
                printf(" ---");
            }
        }
    }
    printf("\n");
}


int Judge_Legal(char board[ROW][COL], int level, int x, int y){
    if(x>=level || y>=level || x<0 || y<0) return 1;
    if(board[x][y]!=' ') return 2;
    return 0;
}




void Player_Do(char board[ROW][COL], int level){
    int c=0;
    int a=0, b=0;
    printf("Tips: 左上角为(1,1),右下角为(%d,%d)\n", level, level);
    printf("玩家走>");
    while(scanf("%d%d", &a,&b))
    {
        int c=0;
        while((c = getchar()) != '\n' && c != EOF);     //清除键盘缓冲区的万能写法
        x=a-1;
        y=b-1;
        if(Judge_Legal(board, level, x, y)==0)
        {
            board[x][y]='X';
            break;
        }
        else if(Judge_Legal(board, level, x, y)==1)
        {
            printf("您输入的位置不合法,请重新输入>");
        }
        else printf("这里已经有棋子了,请重新输入>");
    }

}

void Computer_Do(char board[ROW][COL], int level){
    printf("电脑走\n");
    while(1)
    {
        x=rand()/level;
        y=rand()/level;
        if(Judge_Legal(board, level, x, y)==0)
        {
            board[x][y]='O';
            break;
        }

    }
}

char Judge_Win(char board[ROW][COL], int level, int num){
    int px=0, py=0;
    int count=0;
    char c=board[x][y];
    //printf("x=%d, y=%d \n ", x, y);
    //printf("c=%c\n",c);
    if (c=='X' || c=='O')
    {
        count=0;
        px=x;
        py=0;                                                                           
        while(px>=0 && px<level && py>=0 && py<level)           //一横排
        {

            (board[px][py]==c) ? (count ++) : (count=0);

            if(count>=num)      return c;
            py++;
        }

        count=0;
        py=y;
        px=0;
        while(px>=0 && px<level && py>=0 && py<level)           //一列排
        {   

            (board[px][py]==c) ? (count ++) : (count=0);

            if(count>=num)      return c;
            px++;
        }

        if(x<y)                         //从左上角到右下角
        {
            px=0;
            py=(y-x);
        }
        else
        {
            px=(x-y);
            py=0;
        }
        count=0;
        while(px>=0 && px<level && py>=0 && py<level)
        {

            (board[px][py]==c) ? (count ++) : (count=0);

            if(count>=num)      return c;
            px++;
            py++;
        }

        if( (level-(x+1))>y )        //从左下角到右上角
        {
            px=x+y;
            py=0;
        }
        else
        {
            px=level-1;
            py=y-(level-(x+1));
        }
        count=0;
        while(px>=0 && px<level && py>=0 && py<level)
        {

            (board[px][py]==c) ? (count ++) : (count=0);

            if(count>=num)      return c;
            px--;
            py++;
        }

    }


    for(px=0; px<level; px++)
    {
        for(py=0; py<level; py++)
        {
            if(board[px][py]==' ') goto Loop1;
        }
    }
    return 'q';
Loop1:
    return 'k';
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值