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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hello_simon

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

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

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

打赏作者

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

抵扣说明:

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

余额充值