linux下的c语言五子棋

学习c语言,参照网络资源写了一个c语言版的五子棋。

人机对战为核心,也是难点,目前使用的是评分表的算法,即网络上说的“只顾眼前利益”的算法。这算法逻辑不复杂,但是效果惊人。目前和自己做出来的“电脑”对战,两盘都输了。评分表如下:

分数

电脑

玩家

空格

1

1

活二

60

50

半活二

40

35

死二

10

10

半死二

10

10

活三

950

700

半活三

900

650

死三

100

100

半死三

100

100

活四

6000

3500

半活四

5000

3000

死四

4000

800

半死四

3600

750

活五

20000

15000

半活五

10000

3300

死五

20000

15000

半死五

10000

3300

解释一下其中的活,半活,死,半死:

活:代表几个子是相连的,中间没有空格,两端都至少有一个空格。

半活:代表几个子不是相连的,几个子中间有一个空格,两端都至少有一个空格。

死:代表几个子是相连的,中间没有空格,但有一端紧挨着对方的棋子或有一端正好在棋盘的边界。

半死:代表几个子不是相连的,几个子中间有一个空格,而且一端紧挨着对方的棋子或有一端正好在棋盘的边界。

每个位置的分数的计算方式是各个方向的分数相加,最后找出电脑棋型和玩家棋型的分数的最高的位置为电脑的下棋点下棋。

/**
 * linux环境下的c语言版五子棋
 * @author drawhm@gmail.com
 * @version 2015-11-3
 */

#include <stdlib.h>  
#include <stdio.h> 
#define WIDTH 15
#define HIGHT 15
#define WHITE 0
#define BLACK 1
#define WIN 2

char WHITE_FLAG='O';//大写o
char BLACK_FLAG='@';

char map[WIDTH][HIGHT];
int qinxingPC[WIDTH][HIGHT]={0};
int qinxingPlayer[WIDTH][HIGHT]={0};

int player = BLACK;

int jieguo( int left, int right, int count, int k, char num );
void init_map();
void draw_pc_map();
void draw_player_map();
void draw_map();
int heng(int hang, int lie, char whoFlag);
int shu(int hang, int lie, char whoFlag);
int zuoxie(int hang, int lie, char whoFlag);
int youxie(int hang, int lie, char whoFlag);
int jieguo( int left, int right, int count, int k, char num );
void pcLoad();
void jifeng();
int playerLoad();
int is_win();


int main() {
    int result;
    int nums;
    init_map();
    
    draw_map();
    
    for (nums = 0; nums < 225; nums++) {
        if (player == BLACK) {
            //玩家下子
            printf("please white(%c) play\n",WHITE_FLAG);
            player = WHITE;
            result = playerLoad();
            if( !result ) break;
        } else {
            //电脑下子
            player = BLACK;
            pcLoad(); 
        }
        
        draw_map();
        if ( is_win() ) {
            if (player == WHITE) {
                printf("WHITE(%c) is winner.\n",WHITE_FLAG);
            } else {
                printf("BLACK(%c) is winner.\n",BLACK_FLAG);
            }
            break;
        }
        
    }
    

}

void init_map() {
    int i = 0;
    int j = 0;
    for (i = 0; i < HIGHT; i++) {
        for (j = 0; j < WIDTH; j++) {
            map[i][j] = '+';
        }
    }
}

void draw_pc_map() {
    int i, j, k;
    
    for (i = 0; i < WIDTH; i++) {
        for (j = 0; j < WIDTH; j++) {
            printf("%d",qinxingPC[i][j]);
            if(j<(WIDTH-1)) printf("-");
        }
        putchar('\n');
    }
}

void draw_player_map() {
    int i=0, j=0;
    
    for (i = 0; i < WIDTH; i++) {
        for (j = 0; j < WIDTH; j++) {
            printf("%d",qinxingPlayer[i][j]);
            if(j<(WIDTH-1)) printf("-");
        }
        putchar('\n');
    }
}

void draw_map() {
    int i=0, j=0, k=0;
    
    system("clear");
    
    printf("    X--------------------------->\n");
    printf("    ");
    for (k = 0; k < HIGHT; k++) {
        if( k>=0 && k<=8){
            printf("%d ",k+1);
        }else{
            printf("%d",k+1);
        }
    }
    putchar('\n');
    for (i = 0; i < WIDTH; i++) {
        printf("Y");
        if( i>=0 && i<=8){
            printf("0%d ",i+1);
        }else{
            printf("%d ",i+1);
        }
        for (j = 0; j < WIDTH; j++) {
            putchar(map[i][j]);
            if(j<(WIDTH-1)) putchar('-');
        }
        putchar('\n');
    }
}

int heng(int hang, int lie, char whoFlag){
    int spaceNum=0;//空白数
    int count =1;//几连,包含当前要下的子
    int leftHad=0;//左边是否有同子
    int x=hang;
    int y=lie;
    int liveLeft = 0;
    int liveRight=0;
    
    if( map[hang][lie] != '+' ){
        return 0;
    }
    while( y>0 && ( map[x][y-1]=='+' || map[x][y-1]==whoFlag ) ){
        if( map[x][y-1]=='+' && spaceNum<1 ){//第一个空白
            if( map[x][y-2] != whoFlag ){
                liveLeft = 1;
                break;
            }
            spaceNum++;
            y--;
        }else if( map[x][y-1] == whoFlag ){
            leftHad=1;
            y--;
            count++;
        }else{//第2个空白
            liveLeft=1;
            break;
        }
    }
    
    //如果左边没有同色子,设置空白数为0
    if( !leftHad ){
        spaceNum=0;
    }
    
    y=lie;
    while( y<14 && ( map[x][y+1]=='+' || map[x][y+1]==whoFlag ) ){
        if( map[x][y+1]=='+' && spaceNum<1){//第一个空白
            if( map[x][y+2] != whoFlag ){
                liveRight = 1;
                break;
            }
            spaceNum++;
            y++;
        }else if( map[x][y+1]=='+' && spaceNum>0 ){//第2个空白
            liveRight = 1;
            break;
        }else{
            y++;
            count++;
        }
        
    }
    return jieguo( liveLeft,liveRight, count,spaceNum, whoFlag );
}

int shu(int hang, int lie, char whoFlag){
    int spaceNum=0;//空白数
    int count =1;//几连,包含当前要下的子
    int topHad=0;//上边是否有同子
    int x=hang;
    int y=lie;
    int liveLeft = 0;
    int liveRight=0;
    
    if( map[hang][lie] != '+' ){
        return 0;
    }
    while( x>0 && ( map[x-1][y]=='+' || map[x-1][y]==whoFlag ) ){
        if( map[x-1][y]=='+' && spaceNum<1 ){//第一个空白
            if( map[x-2][y] != whoFlag ){
                liveLeft = 1;
                break;
            }
            spaceNum++;
            x--;
        }else if( map[x-1][y] == whoFlag ){
            topHad=1;
            x--;
            count++;
        }else{//第2个空白
            liveLeft=1;
            break;
        }
    }
    
    //如果左边没有同色子,设置空白数为0
    if( !topHad ){
        spaceNum=0;
    }
    x=hang;
    while( x<14 && ( map[x+1][y]=='+' || map[x+1][y]==whoFlag ) ){
        if( map[x+1][y]=='+' && spaceNum<1){//第一个空白
            if( map[x+2][y] != whoFlag ){
                liveRight = 1;
                break;
            }
            spaceNum++;
            x++;
        }else if( map[x+1][y]=='+' && spaceNum>0 ){//第2个空白
            liveRight = 1;
            break;
        }else{
            x++;
            count++;
        }
        
    }
    return jieguo( liveLeft,liveRight, count,spaceNum, whoFlag );
}


// +-+-+-@-+-+
// +-+-@-+-+
// +-@-+-+-+
int zuoxie(int hang, int lie, char whoFlag){
    int spaceNum=0;//空白数
    int count =1;//几连,包含当前要下的子
    int topHad=0;//上边是否有同子
    int x=hang;
    int y=lie;
    int liveLeft = 0;
    int liveRight=0;
    
    if( map[hang][lie] != '+' ){
        return 0;
    }
    //向下
    while( x<14 && y>0 && ( map[x+1][y-1]=='+' || map[x+1][y-1]==whoFlag ) ){
        if( map[x+1][y-1]=='+' && spaceNum<1 ){//第一个空白
            if( map[x+2][y-2] != whoFlag ){
                liveLeft = 1;
                break;
            }
            spaceNum++;
            x++;
            y--;
        }else if( map[x+1][y-1] == whoFlag ){
            topHad=1;
            x++;
            y--;
            count++;
        }else{//第2个空白
            liveLeft=1;
            break;
        }
    }
        
    //如果上边没有同色子,设置空白数为0
    if( !topHad ){
        spaceNum=0;
    }

    x=hang;
    y=lie;
    
    //向上
    while( x>0 && y<14 && ( map[x-1][y+1]=='+' || map[x-1][y+1]==whoFlag ) ){
        if( map[x-1][y+1]=='+' && spaceNum<1){//第一个空白
            if( map[x-2][y+2] != whoFlag ){
                liveRight = 1;
                break;
            }
            spaceNum++;
            x--;
            y++;
        }else if( map[x-1][y+1]=='+' && spaceNum>0 ){//第2个空白
            liveRight = 1;
            break;
        }else{
            x--;
            y++;
            count++;
        }
        
    }
    return jieguo( liveLeft,liveRight, count,spaceNum, whoFlag );
}

int youxie(int hang, int lie, char whoFlag){
    int spaceNum=0;//空白数
    int count =1;//几连,包含当前要下的子
    int topHad=0;//上边是否有同子
    int x=hang;
    int y=lie;
    int liveLeft = 0;
    int liveRight=0;
    
    if( map[hang][lie] != '+' ){
        return 0;
    }
    //向上
    while( x>0 && y>0 && ( map[x-1][y-1]=='+' || map[x-1][y-1]==whoFlag ) ){
        if( map[x-1][y-1]=='+' && spaceNum<1 ){//第一个空白
            if( map[x-2][y-2] != whoFlag ){
                liveLeft = 1;
                break;
            }
            spaceNum++;
            x--;
            y--;
        }else if( map[x-1][y-1] == whoFlag ){
            topHad=1;
            x--;
            y--;
            count++;
        }else{//第2个空白
            liveLeft=1;
            break;
        }
    }
        
    //如果上边没有同色子,设置空白数为0
    if( !topHad ){
        spaceNum=0;
    }

    x=hang;
    y=lie;
    
    //向下
    while( x<14 && y<14 && ( map[x+1][y+1]=='+' || map[x+1][y+1]==whoFlag ) ){
        if( map[x+1][y+1]=='+' && spaceNum<1){//第一个空白
            if( map[x+2][y+2] != whoFlag ){
                liveRight = 1;
                break;
            }
            spaceNum++;
            x++;
            y++;
        }else if( map[x+1][y+1]=='+' && spaceNum>0 ){//第2个空白
            liveRight = 1;
            break;
        }else{
            x++;
            y++;
            count++;
        }
        
    }
    return jieguo( liveLeft,liveRight, count,spaceNum, whoFlag );
}

int jieguo( int left, int right, int count, int k, char num ){
    if( count ==1 ){
        return 1;
    }else if( count == 2 ){
        if( left && right ){//左右两边都是空的
            if( k==0 ){
                //电脑60
                return num == BLACK_FLAG ? 60 : 50;
            }else{
                return num == BLACK_FLAG ? 40 : 35;
            }
        }else if( !left && !right ){
            return 1;
        }else{
            return 10;
        }
    }else if( count == 3 ){
        
        if( left && right ){//左右两边都是空的
            if( k==0 ){
                //电脑950
                return num == BLACK_FLAG ? 950 : 700;
            }else{
                return num == BLACK_FLAG ? 900 : 650;
            }
        }else if( !left && !right ){
            return 1;
        }else{
            return 100;
        }
    }else if( count == 4 ){
        if( left && right ){//左右两边都是空的
            if( k==0 ){
                return num == BLACK_FLAG ? 6000 : 3500;
            }else{
                return num == BLACK_FLAG ? 5000 : 3000;
            }
        }else if( !left && !right ){
            return 1;
        }else{
            if( k==0 ){
                return num == BLACK_FLAG ? 4000 : 800;
            }else{
                return num == BLACK_FLAG ? 3600 : 750;
            }
        }
    }else{
        if( k==0 ){
            return num == BLACK_FLAG ? 20000 : 15000;
        }else{
            return num == BLACK_FLAG ? 10000 : 3300;
        }
    }
    
}

void pcLoad(){
    jifeng();
    
    int count=0;
    int hang=0;
    int lie=0;
    int i=0;
    int j=0;
    for( i=0; i< 15; i++ ){
        for( j=0; j< 15; j++ ){
            if( qinxingPC[i][j] > count ){
                count = qinxingPC[i][j];
                hang = i;
                lie = j;
            }
            if( qinxingPlayer[i][j] > count ){
                count = qinxingPlayer[i][j];
                hang = i;
                lie = j;
            }
        }
    }
    
    printf("qinxingPC[%d][%d]:%d\n",hang,lie,qinxingPC[hang][lie]);
    printf("qinxingPlayer[%d][%d]:%d\n",hang,lie,qinxingPlayer[hang][lie]);
    
    if( map[hang][lie] == '+' ){
        map[hang][lie] = BLACK_FLAG;
    }
    
}

//记分
void jifeng(){
    int n=0;
    int m=0;
    for( n=0;n<15;n++){
        for( m=0;m<15; m++ ){
            qinxingPC[n][m] = heng(n,m,BLACK_FLAG)+shu(n,m,BLACK_FLAG)+zuoxie(n,m,BLACK_FLAG)+youxie(n,m,BLACK_FLAG);
            qinxingPlayer[n][m] = heng(n,m,WHITE_FLAG)+shu(n,m,WHITE_FLAG)+zuoxie(n,m,WHITE_FLAG)+youxie(n,m,WHITE_FLAG);
        }
    }
    
}

//玩家下子
int playerLoad() {
    int x, y;
    int res;
    
    printf("input y x:");
    scanf("%d %d", &x, &y);
    
    if(x<0||y<0||x>HIGHT||y>WIDTH){
        printf("input error,again\n");
        while ((getchar()) != '\n');
        res = playerLoad();
        if( res == 1 ) return 1;
    }
    
    x--;
    y--;
    if (map[x][y] == '+') {
        if (player == WHITE) {
            map[x][y] = WHITE_FLAG;
        }
    } else {
        printf("input error2,again\n");
        while ((getchar()) != '\n');
        playerLoad();
        if( res == 1 ) return 1;
    }
    return 1;
}

int is_win() {
    char m;
    int i, j;

    if (player == WHITE) m = WHITE_FLAG;
    else m = BLACK_FLAG;
    
    for (i = 0; i < HIGHT; i++) {
        for (j = 0; j < WIDTH; j++) {
            if (map[i][j] == m) {
                if ((i + 4) < HIGHT) {
                    if (map[i + 1][j] == m && map[i + 2][j] == m && map[i + 3][j] == m && map[i + 4][j] == m) return 1;
                }
                if ((j + 4) < WIDTH) {
                    if (map[i][j + 1] == m && map[i][j + 2] == m && map[i][j + 3] == m && map[i][j + 4] == m) return 1;
                }
                if ((i + 4) < HIGHT && (j + 4) < WIDTH) {
                    if (map[i + 1][j + 1] == m && map[i + 2][j + 2] == m && map[i + 3][j + 3] == m && map[i + 4][j + 4] == m) return 1;
                }
                if ((i + 4) < HIGHT && (j - 4) >= 0) {
                    if (map[i + 1][j - 1] == m && map[i + 2][j - 2] == m && map[i + 3][j - 3] == m && map[i + 4][j - 4] == m) return 1;
                }
            }
        }
    }
    return 0;
}

第一版

第二版

第三版(人机大战)

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 在 Linux 下编写 C 语言程序需要一个编译器,如 GCC。可以使用命令行工具编写代码,并使用 GCC 编译器编译代码。例如,在命令行中输入 "gcc -o programname programname.c" 可以将 programname.c 文件编译为可执行文件 programname。然后在命令行运行 "./programname" 即可运行编译后的程序。 ### 回答2: LinuxC语言编程是非常常见的一种开发环境与方式。Linux操作系统提供了完善的C语言开发工具链,包括编译器、调试工具、开发库等,因此在Linux下进行C语言编程是非常方便和高效的。 首先,Linux下最常用的C语言编译器是GNU编译器套装(GCC)。GCC是一个开源的编译器套件,支持多种编程语言,其中包括C语言。使用GCC编译器,可以将C语言源代码编译成可执行的机器代码,从而在Linux操作系统上运行。 其次,Linux提供了丰富的调试工具,如GNU调试器(GDB)。GDB是一个功能强大的调试工具,可以通过设置断点、查看变量值、跟踪程序执行流程来帮助开发人员进行代码调试。使用GDB可以快速定位并解决代码中的错误。 此外,Linux还提供了大量的开发库和工具,如标准C库(libc)、各种系统库和第三方库等。这些库和工具能够极大地提升C语言编程的效率和功能,开发人员可以利用这些库来实现各种功能,如文件操作、网络通信、图形界面等。 在Linux下进行C语言编程还有一个显著的优势就是开源社区的支持。Linux有庞大的开源社区,有着丰富的资源和经验,开发人员可以从中获取帮助和学习。在开源社区中,开发人员可以共享自己的代码、学习他人的经验,并且可以参与到各种开源项目中去,提升自己的技能和知识。 综上所述,LinuxC语言编程是非常强大和便利的。通过Linux提供的工具链、库和开源社区的支持,开发人员可以高效地进行C语言编程,实现各种功能和项目。 ### 回答3: Linux下的C语言编程是一种广泛应用的编程方式。Linux作为一种开源操作系统,在C语言编程方面具有许多优势和特点。 首先,Linux下的C语言编程可以充分利用Linux操作系统的强大功能和丰富的系统接口。通过使用Linux的系统调用接口,我们可以直接对文件、进程、网络等进行操作,实现更高级的功能。同时,Linux提供了许多方便的开发工具和库,比如GCC编译器、C库,使得C语言编程更加方便和高效。 其次,Linux下的C语言编程具有良好的可移植性。由于Linux操作系统的开源性质,C语言编程在Linux下编写的程序可以在其他操作系统上进行移植。这为开发者提供了更大的自由度和灵活性,使得他们能够更好地跨平台开发和移植应用程序。 另外,Linux下的C语言编程也提供了强大的调试和性能优化工具。开发者可以使用诸如gdb、valgrind等工具对C程序进行调试和性能分析,以找出潜在的问题并提高程序的效率。这些工具的存在大大提高了开发者对程序的控制和管理能力。 总结而言,Linux下的C语言编程是一种功能强大、可移植性高且开发工具丰富的编程方式。通过利用Linux操作系统的强大功能和丰富接口,开发者可以编写高效、稳定且可移植的应用程序。这使得Linux下的C语言编程成为了许多开发者的首选。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello_simon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值