電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[C]C reversi黑白棋
前往頁面 1, 2  下一頁
 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式初級班:語法及基礎概念
上一篇主題 :: 下一篇主題  
發表人 內容
neilshih
Neilshih專區 板主


註冊時間: 2007-06-03
文章: 33
來自: 地球
20.01 果凍幣

發表發表於: 2007-6-3, PM 6:45 星期日    文章主題: [C]C reversi黑白棋 引言回覆

代碼:
#include <stdio.h>
#include <ctype.h>
#define SIZE 6
void display(char board[][SIZE]);
int valid_moves(char board[][SIZE], int moves[][SIZE], char player);
void make_move(char board[][SIZE], int row, int col, char player);
void computer_move(char board[][SIZE], int moves[][SIZE], char player);
int get_score(char board[][SIZE], char player);
int best_move(char board[][SIZE], int moves[][SIZE], char player);
main(){
    char board[SIZE][SIZE] = { 0 };
    int moves[SIZE][SIZE] = { 0 };
    int row = 0;
    int col = 0;
    int no_of_games = 0;
    int no_of_moves = 0;
    int invalid_moves = 0;
    int comp_score = 0;
    int user_score = 0;
    char again = 0;
    int player = 0;
    char y = 0;
    int x = 0;
   
    printf("\nREVERSI\n");
    printf("Press enter to start.");
    scanf("%c", &row);
    do{
        player = ++no_of_games % 2;
        no_of_moves = 4;
        for(row = 0; row < SIZE; row++)
            for(col = 0; col < SIZE; col++)
                board[row][col] = ' ';
        board[SIZE/2 - 1][SIZE/2 - 1] =board[SIZE/2][SIZE/2] = 'O';
        board[SIZE/2 - 1][SIZE/2] = board[SIZE/2][SIZE/2 - 1] = '@';
        do{
            display(board);
            if(player++ %2){
                if(valid_moves(board, moves, 'O')){
                    for(;;){
                        fflush(stdin);
                        printf("Please enter your move (row column):");
                        scanf("%d%c",&x ,&y);
                        y = tolower(y) - 'a';
                        x--;
                        if(x >= 0 && y >= 0 && x < SIZE && y < SIZE && moves[x][y]){
                            make_move(board, x, y, 'O');
                            no_of_moves++;
                            break;
                        }
                        else
                            printf("Not a valid move, try again.\n");
                    }
                }
                else
                    if(++invalid_moves < 2){
                        fflush(stdin);
                        printf("\nYou have to pass, press return");
                        scanf("%c", &again);
                    }
                    else
                        printf("\nNeither of us can go, so the game is over.");
            }
            else{
                if(valid_moves(board, moves, '@')){
                    invalid_moves = 0;
                    computer_move(board, moves, '@');
                    no_of_moves++;
                }
                else{
                    if(++invalid_moves < 2)
                        printf("\nI have to pass, your go\n");
                    else
                        printf("\nNeither of us can go, so the game is over\n");
                }
            }
        }while(no_of_moves < SIZE*SIZE && invalid_moves < 2);
        display(board);
        comp_score = user_score = 0;
        for(row = 0; row < SIZE; row++)
            for(col = 0; col < SIZE; col++){
                comp_score += board[row][col] == '@';
                user_score += board[row][col] == 'O';
            }
            printf("The final score is:\n");
            printf("Computer %d\n User %d\n\n", comp_score, user_score);
            fflush(stdin);
            printf("Do you want to play again (y/n):");
            scanf("%c", &again);
    }while(tolower(again) == 'y');
    printf("\nGoodBye\n");
    system("PAUSE");
}

void display(char board[][SIZE]){
    int row = 0;
    int col = 0;
    char col_label = 'a';
    printf("\n   ");
    for(col = 0; col < SIZE; col++)
        printf("  %c ", col_label + col);
    printf("\n");
    for(row = 0; row < SIZE; row++){
        printf("   +");
        for(col = 0; col < SIZE; col++)
            printf("---+");
        printf("\n%2d |", row+1);
        for(col = 0; col < SIZE; col++)
            printf(" %c |", board[row][col]);
        printf("\n");
    }     
    printf("   +"); 
    for(col = 0; col < SIZE; col++)
        printf("---+");
    printf("\n\n");
}
   
int valid_moves(char board[][SIZE], int moves[][SIZE], char player){
    int rowdelta = 0;
    int coldelta = 0;
    int row = 0;
    int col = 0;
    int x = 0;
    int y = 0;
    int no_of_moves = 0;
    char opponent = (player == 'O')? '@' : 'O';
   
    for(row = 0; row < SIZE; row++)
        for(col = 0; col < SIZE; col++)
            moves[row][col] = 0; 
    for(row = 0; row < SIZE; row++)
        for(col = 0; col < SIZE; col++){
            if(board[row][col] != ' ')
                continue;
            for(rowdelta = -1; rowdelta <= 1; rowdelta++)
                for(coldelta = -1; coldelta <= 1; coldelta++){
                    if(row + rowdelta < 0 || row + rowdelta >= SIZE ||
                    col + coldelta < 0 || col + coldelta > SIZE ||
                    (rowdelta == 0 && coldelta == 0))
                        continue;
                    if(board[row + rowdelta][col + coldelta] == opponent){
                        x = row + rowdelta;
                        y = col + coldelta;
                        for(;;){
                            x += rowdelta;
                            y += coldelta;
                            if(x < 0 || x >= SIZE || y < 0 || y >= SIZE)
                                break;
                            if(board[x][y] == ' ')
                                break;
                            if(board[x][y] == player){
                                moves[row][col] = 1;
                                no_of_moves++;
                                break;
                            }
                        }
                    }
                }
        }
    return no_of_moves;
}

void make_move(char board[][SIZE], int row, int col, char player){
    int rowdelta = 0;
    int coldelta = 0;
    int x = 0;
    int y = 0;
    char opponent = (player == 'O')? '@' : 'O';
    board[row][col]  = player;
    for(rowdelta = -1; rowdelta <= 1; rowdelta++)
        for(coldelta = -1; coldelta <= 1; coldelta++){
            if(row + rowdelta < 0 || row + rowdelta >= SIZE ||
                col + coldelta < 0 || col + coldelta > SIZE ||
                (rowdelta == 0 && coldelta == 0))
                continue;
            if(board[row + rowdelta][col + coldelta] == opponent){
                x = row + rowdelta;
                y = col + coldelta;
                for(;;){
                    x += rowdelta;
                    y += coldelta;
                    if(x < 0 || x >= SIZE || y < 0 || y >= SIZE)
                        break;
                    if(board[x][y] == ' ')
                        break;
                    if(board[x][y] == player){
                        while(board[x -= rowdelta][y -= coldelta] == opponent)
                            board[x][y] = player;
                        break;
                    }
                   
                }
            }
        }
}                       
int get_score(char board[][SIZE], char player){
    int score = 0;
    int row = 0;
    int col = 0;
    char opponent = player == 'O' ? '@' : 'O';
    for(row = 0; row < SIZE; row++)
        for(col = 0; col < SIZE; col++){
            score -= board[row][col] == opponent;
            score += board[row][col] == player;
        }
        return score;
}

int best_move(char board[][SIZE], int moves[][SIZE], char player){
    int row = 0;
    int col = 0;
    int i = 0;
    int j = 0;
    char opponent = player == 'O' ? '@' : 'O';
    char new_board[SIZE][SIZE] = { 0 };
    int score = 0;
    int new_score = 0;
   
    for(row = 0; row < SIZE; row++)
        for(col = 0; col < SIZE; col++){
            if(!moves[row][col])
                continue;
            for(i = 0; i < SIZE; i++)
                for(j = 0; j < SIZE; j++)
                    new_board[i][j] = board[i][j];
            make_move(new_board, row, col, player);
            new_score = get_score(new_board, player);
            if(score < new_score)
                score = new_score;
        }
        return score;
}

void computer_move(char board[][SIZE], int moves[][SIZE], char player){
    int row = 0;
    int col = 0;
    int best_row = 0;
    int best_col = 0;
    int i = 0;
    int j = 0;
    int new_score = 0;
    int score = 0;
    char temp_board[SIZE][SIZE];
    int temp_moves[SIZE][SIZE];
    char opponent = (player == 'O')? '@' : 'O';
   
    for(row = 0; row < SIZE; row++)
        for(col = 0; col < SIZE; col++){
            if(moves[row][col] == 0)
                continue;
            for(i = 0; i < SIZE; i++)
                for(j = 0; j < SIZE; j++)
                    temp_board[i][j] = board[i][j];
            make_move(temp_board, row, col, player);
            valid_moves(temp_board, temp_moves, opponent);
            new_score = best_move(temp_board, temp_moves, opponent);
            if(score < new_score){
                score = new_score;
                best_row = row;
                best_col = col;
            }
        }
        make_move(board, best_row, best_col, player);
}


Ivor Horton C程式語言設計手冊上的範例
電腦笨笨的
可以試著把它改強一點


neilshih 在 2007-6-3, PM 9:29 星期日 作了第 1 次修改
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
yag
Site Admin


註冊時間: 2007-05-02
文章: 688

2673.35 果凍幣

發表發表於: 2007-6-3, PM 6:55 星期日    文章主題: Re: C reversi黑白棋 引言回覆

neilshih 寫到:
Ivor Horton C程式語言設計手冊上的範例
電腦笨笨的
可以試著把它改強一點
我打的縮排他都沒顯示@@
真抱歉


要貼程式碼的時候,要善用BBCode的Code標籤唷~
我已經幫你加上了,這樣才會顯示出縮排
唔...書上的範例最好是不要整個貼上來,除非你有改過,如你所說的,可以改強一點,之後再放上來
雖然只有一個範例應該沒關係,不過畢竟那是人家書上的範例,可能會有版權問題,還是要注意一下

話說,reversi是什麼意思呀?
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
neilshih
Neilshih專區 板主


註冊時間: 2007-06-03
文章: 33
來自: 地球
20.01 果凍幣

發表發表於: 2007-6-3, PM 7:57 星期日    文章主題: Re: C reversi黑白棋 引言回覆

夾棋
又叫黑白棋、蘋果棋
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
yag
Site Admin


註冊時間: 2007-05-02
文章: 688

2673.35 果凍幣

發表發表於: 2007-6-3, PM 11:15 星期日    文章主題: Re: C reversi黑白棋 引言回覆

neilshih 寫到:
夾棋
又叫黑白棋、蘋果棋


原來如此,我都不知道黑白棋的英文是Reversi @_@"
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
neilshih
Neilshih專區 板主


註冊時間: 2007-06-03
文章: 33
來自: 地球
20.01 果凍幣

發表發表於: 2007-6-5, AM 1:16 星期二    文章主題: Re: C reversi黑白棋 引言回覆

那本書上寫的有一些錯誤

我改了幾個出來了

可是還有一個bug

當在玩第二輪時電腦只會下在1a的位子

有時間又無聊的人可以來改一改
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
angie3352
稍嫌羞澀的路人


註冊時間: 2008-01-06
文章: 3

0.00 果凍幣

發表發表於: 2008-1-6, PM 5:04 星期日    文章主題: 引言回覆

我是程式的初學者...
可以請您解釋一下該程式碼嗎??
有不少部分看不懂....
回頂端
檢視會員個人資料 發送私人訊息
yag
Site Admin


註冊時間: 2007-05-02
文章: 688

2673.35 果凍幣

發表發表於: 2008-1-6, PM 5:58 星期日    文章主題: 引言回覆

angie3352 寫到:
我是程式的初學者...
可以請您解釋一下該程式碼嗎??
有不少部分看不懂....

把看不懂的部份提出來問吧
這樣起碼可以不用解釋你看得懂的部份
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
angie3352
稍嫌羞澀的路人


註冊時間: 2008-01-06
文章: 3

0.00 果凍幣

發表發表於: 2008-1-6, PM 6:07 星期日    文章主題: 引言回覆

引言回覆:
把看不懂的部份提出來問吧
這樣起碼可以不用解釋你看得懂的部份

可以請您完整解釋嗎??
因為我打算改用物件的觀念去改寫他
可是有些地方改寫起來跟我想像中的不一樣
我想大概是我誤解了您原程式碼的意思的緣故吧
所以可以的話能請您完整解釋一下嗎??
回頂端
檢視會員個人資料 發送私人訊息
fire231
散播福音的祭司


註冊時間: 2007-09-15
文章: 152

322.55 果凍幣

發表發表於: 2008-1-7, PM 6:25 星期一    文章主題: 引言回覆

這遊戲的輸入方式好囧..

要先輸入數字

重點是~是英文版的~XD
回頂端
檢視會員個人資料 發送私人訊息
neilshih
Neilshih專區 板主


註冊時間: 2007-06-03
文章: 33
來自: 地球
20.01 果凍幣

發表發表於: 2008-1-7, PM 10:02 星期一    文章主題: 引言回覆

angie3352 寫到:
引言回覆:
把看不懂的部份提出來問吧
這樣起碼可以不用解釋你看得懂的部份

可以請您完整解釋嗎??
因為我打算改用物件的觀念去改寫他
可是有些地方改寫起來跟我想像中的不一樣
我想大概是我誤解了您原程式碼的意思的緣故吧
所以可以的話能請您完整解釋一下嗎??

你先下,下完換電腦下。
兩個人輪流下
下到棋盤滿或兩個人都不能下就結束了
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
angie3352
稍嫌羞澀的路人


註冊時間: 2008-01-06
文章: 3

0.00 果凍幣

發表發表於: 2008-1-8, AM 12:03 星期二    文章主題: 引言回覆

neilshih 寫到:
angie3352 寫到:
引言回覆:
把看不懂的部份提出來問吧
這樣起碼可以不用解釋你看得懂的部份

可以請您完整解釋嗎??
因為我打算改用物件的觀念去改寫他
可是有些地方改寫起來跟我想像中的不一樣
我想大概是我誤解了您原程式碼的意思的緣故吧
所以可以的話能請您完整解釋一下嗎??

你先下,下完換電腦下。
兩個人輪流下
下到棋盤滿或兩個人都不能下就結束了

我的疑問是程式碼不是遊戲規則...也不是英文字看不懂....
回頂端
檢視會員個人資料 發送私人訊息
yag
Site Admin


註冊時間: 2007-05-02
文章: 688

2673.35 果凍幣

發表發表於: 2008-1-8, PM 2:21 星期二    文章主題: 引言回覆

angie3352 寫到:
引言回覆:
把看不懂的部份提出來問吧
這樣起碼可以不用解釋你看得懂的部份

可以請您完整解釋嗎??
因為我打算改用物件的觀念去改寫他
可是有些地方改寫起來跟我想像中的不一樣
我想大概是我誤解了您原程式碼的意思的緣故吧
所以可以的話能請您完整解釋一下嗎??

這程式碼不是我寫的,也不是我貼的,上面有說是某本書的範例
要完整解釋頗麻煩,你說「有些地方改寫起來跟我想像中的不一樣」
不如就把那不一樣的地方說出來討論看看?
又或者把你改寫的程式碼貼上來,要指出錯誤也比整個解釋來得省時得多
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
babu61509
散播福音的祭司


註冊時間: 2007-08-26
文章: 142

681.01 果凍幣

發表發表於: 2008-1-8, PM 11:29 星期二    文章主題: Re: [C]C reversi黑白棋 引言回覆

稍微解釋一下函數功能... 大概看一下而已 @_@ 有錯請指正

void display(char board[][SIZE]);
顯示目前棋盤 (傳入棋盤陣列)

int valid_moves(char board[][SIZE], int moves[][SIZE], char player);
檢查是否為有效移動 (棋盤陣列,可下子陣列[0為不能下],誰下的)

void make_move(char board[][SIZE], int row, int col, char player);
下子後處理,就是翻棋子 (棋盤陣列,列,行,誰下的)

void computer_move(char board[][SIZE], int moves[][SIZE], char player);
電腦下子 (棋盤陣列,可下子陣列[0為不能下],誰下的)

int get_score(char board[][SIZE], char player);
下子計算分數用 (棋盤陣列,誰下的)

int best_move(char board[][SIZE], int moves[][SIZE], char player);
計算分數最高的下子位置 (棋盤陣列,可下子陣列[0為不能下],誰下的)

應該是這樣吧@_@

_________________
已經畢業了!!
回頂端
檢視會員個人資料 發送私人訊息
neilshih
Neilshih專區 板主


註冊時間: 2007-06-03
文章: 33
來自: 地球
20.01 果凍幣

發表發表於: 2008-1-8, PM 11:50 星期二    文章主題: Re: [C]C reversi黑白棋 引言回覆

你說的都對了
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
a19870504
對這略感興趣的新人


註冊時間: 2008-01-11
文章: 17

0.00 果凍幣

發表發表於: 2008-1-11, AM 9:32 星期五    文章主題: 引言回覆

黑白棋?這是五子棋還是圍棋阿?
要是五子棋感覺還可以理解
要是圍棋那就天阿.......有夠複雜的東西
光是普通規則就有夠多的
還要用程式碼寫出來
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 雅虎訊息通 MSN Messenger
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式初級班:語法及基礎概念 所有的時間均為 台灣時間 (GMT + 8 小時)
前往頁面 1, 2  下一頁
1頁(共2頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作