📄 gomoku.c
字号:
/* gomoku - 5 in a row game Author: ? *//* This program plays a very old Japanese game called GO-MOKU, perhaps better known as 5-in-line. The game is played on a board with 19 x 19 squares, and the object of the game is to get 5 stones in a row.*/#include <sys/types.h>#include <curses.h>#include <ctype.h>#include <stdlib.h>#include <unistd.h>/* Size of the board */#define SIZE 19/* Importance of attack (1..16) */#define AttackFactor 4/* Value of having 0, 1,2,3,4 or 5 pieces in line */int Weight[7] = {0, 0, 4, 20, 100, 500, 0};#define Null 0#define Horiz 1#define DownLeft 2#define DownRight 3#define Vert 4/* The two players */#define Empty 0#define Cross 1#define Nought 2char PieceChar[Nought + 1] = {' ', 'X', '0'};int Board[SIZE + 1][SIZE + 1];/* The board */int Player; /* The player whose move is next */int TotalLines; /* The number of Empty lines left */int GameWon; /* Set if one of the players has won */int Line[4][SIZE + 1][SIZE + 1][Nought + 1];/* Value of each square for each player */int Value[SIZE + 1][SIZE + 1][Nought + 1];int X, Y; /* Move coordinates */char Command; /* Command from keyboard */int AutoPlay = FALSE; /* The program plays against itself */_PROTOTYPE(void Initialize, (void));_PROTOTYPE(int Abort, (char *s));_PROTOTYPE(void WriteLetters, (void));_PROTOTYPE(void WriteLine, (int j, int *s));_PROTOTYPE(void WriteBoard, (int N, int *Top, int *Middle, int *Bottom));_PROTOTYPE(void SetUpScreen, (void));_PROTOTYPE(void GotoSquare, (int x, int y));_PROTOTYPE(void PrintMove, (int Piece, int X, int Y));_PROTOTYPE(void ClearMove, (void));_PROTOTYPE(void PrintMsg, (char *Str));_PROTOTYPE(void ClearMsg, (void));_PROTOTYPE(void WriteCommand, (char *S));_PROTOTYPE(void ResetGame, (int FirstGame));_PROTOTYPE(int OpponentColor, (int Player));_PROTOTYPE(void BlinkRow, (int X, int Y, int Dx, int Dy, int Piece));_PROTOTYPE(void BlinkWinner, (int Piece, int X, int Y, int WinningLine));_PROTOTYPE(int Random, (int x));_PROTOTYPE(void Add, (int *Num));_PROTOTYPE(void Update, (int Lin[], int Valu[], int Opponent));_PROTOTYPE(void MakeMove, (int X, int Y));_PROTOTYPE(int GameOver, (void));_PROTOTYPE(void FindMove, (int *X, int *Y));_PROTOTYPE(char GetChar, (void));_PROTOTYPE(void ReadCommand, (int X, int Y, char *Command));_PROTOTYPE(void InterpretCommand, (int Command));_PROTOTYPE(void PlayerMove, (void));_PROTOTYPE(void ProgramMove, (void));_PROTOTYPE(int main, (void));/* Set terminal to raw mode. */void Initialize(){ srand(getpid() + 13); /* Initialize the random seed with our pid */ initscr(); raw(); noecho(); clear();}/* Reset terminal and exit from the program. */int Abort(s)char *s;{ move(LINES - 1, 0); refresh(); endwin(); exit(0);}/* Set up the screen ----------------------------------------------- *//* Write the letters */void WriteLetters(){ int i; addch(' '); addch(' '); for (i = 1; i <= SIZE; i++) printw(" %c", 'A' + i - 1); addch('\n');}/* Write one line of the board */void WriteLine(j, s)int j;int *s;{ int i; printw("%2d ", j); addch(s[0]); for (i = 2; i <= SIZE - 1; i++) { addch(s[1]); addch(s[2]); } addch(s[1]); addch(s[3]); printw(" %-2d\n", j);}/* Print the Empty board and the border */void WriteBoard(N, Top, Middle, Bottom)int N;int *Top, *Middle, *Bottom;{ int j; move(1, 0); WriteLetters(); WriteLine(N, Top); for (j = N - 1; j >= 2; j--) WriteLine(j, Middle); WriteLine(1, Bottom); WriteLetters();}/* Sets up the screen with an Empty board */void SetUpScreen(){ int top[4], middle[4], bottom[4]; top[0] = ACS_ULCORNER; top[1] = ACS_HLINE; top[2] = ACS_TTEE; top[3] = ACS_URCORNER; middle[0] = ACS_LTEE; middle[1] = ACS_HLINE; middle[2] = ACS_PLUS; middle[3] = ACS_RTEE; bottom[0] = ACS_LLCORNER; bottom[1] = ACS_HLINE; bottom[2] = ACS_BTEE; bottom[3] = ACS_LRCORNER; WriteBoard(SIZE, top, middle, bottom);}/* Show moves ----------------------------------------------- */void GotoSquare(x, y)int x, y;{ move(SIZE + 2 - y, 1 + x * 2);}/* Prints a move */void PrintMove(Piece, X, Y)int Piece;int X, Y;{ move(22, 49); printw("%c %c %d", PieceChar[Piece], 'A' + X - 1, Y); clrtoeol(); GotoSquare(X, Y); addch(PieceChar[Piece]); GotoSquare(X, Y); refresh();}/* Clears the line where a move is displayed */void ClearMove(){ move(22, 49); clrtoeol();}/* Message handling ---------------------------------------------- *//* Prints a message */void PrintMsg(Str)char *Str;{ mvprintw(23, 1, "%s", Str);}/* Clears the message about the winner */void ClearMsg(){ move(23, 1); clrtoeol();}/* Highlights the first letter of S */void WriteCommand(S)char *S;{ standout(); addch(*S); standend(); printw("%s", S + 1);}/* Display the board ----------------------------------------------- *//* Resets global variables to start a new game */void ResetGame(FirstGame)int FirstGame;{ int I, J; int C, D; SetUpScreen(); if (FirstGame) { move(1, 49); addstr("G O M O K U"); move(3, 49); WriteCommand("Newgame "); WriteCommand("Quit "); move(5, 49); WriteCommand("Auto"); move(7, 49); WriteCommand("Play"); move(9, 49); WriteCommand("Hint"); move(14, 60); WriteCommand("Left, "); WriteCommand("Right, "); move(16, 60); WriteCommand("Up, "); WriteCommand("Down"); move(18, 60); standout(); addstr("SPACE"); move(20, 49); WriteCommand(" NOTE: Use Num Lock & arrows"); standend(); mvaddstr(14, 49, "7 8 9"); mvaddch(15, 52, ACS_UARROW); mvaddch(16, 49, '4'); addch(ACS_LARROW); mvaddch(16, 54, ACS_RARROW); addch('6'); mvaddch(17, 52, ACS_DARROW); mvaddstr(18, 49, "1 2 3"); FirstGame = FALSE; } else { ClearMsg(); ClearMove(); } /* Clear tables */ for (I = 1; I <= SIZE; I++) for (J = 1; J <= SIZE; J++) { Board[I][J] = Empty; for (C = Cross; C <= Nought; C++) { Value[I][J][C] = 0; for (D = 0; D <= 3; D++) Line[D][I][J][C] = 0; } } /* Cross starts */ Player = Cross; /* Total number of lines */ TotalLines = 2 * 2 * (SIZE * (SIZE - 4) + (SIZE - 4) * (SIZE - 4)); GameWon = FALSE;}int OpponentColor(Player)int Player;{ if (Player == Cross) return Nought; else return Cross;}/* Blink the row of 5 stones */void BlinkRow(X, Y, Dx, Dy, Piece)int X, Y, Dx, Dy, Piece;{ int I; attron(A_BLINK); for (I = 1; I <= 5; I++) { GotoSquare(X, Y); addch(PieceChar[Piece]); X = X - Dx; Y = Y - Dy; } attroff(A_BLINK);}/* Prints the 5 winning stones in blinking color */void BlinkWinner(Piece, X, Y, WinningLine)int Piece, X, Y, WinningLine;{ /* Used to store the position of the winning move */ int XHold, YHold; /* Change in X and Y */ int Dx, Dy; /* Display winning move */ PrintMove(Piece, X, Y); /* Preserve winning position */ XHold = X; YHold = Y; switch (WinningLine) { case Horiz: { Dx = 1; Dy = 0; break; } case DownLeft: { Dx = 1; Dy = 1; break; } case Vert: { Dx = 0; Dy = 1; break; } case DownRight: { Dx = -1; Dy = 1; break; } } /* Go to topmost, leftmost */ while (Board[X + Dx][Y + Dy] != Empty && Board[X + Dx][Y + Dy] == Piece) { X = X + Dx; Y = Y + Dy; } BlinkRow(X, Y, Dx, Dy, Piece); /* Restore winning position */ X = XHold; Y = YHold; /* Go back to winning square */ GotoSquare(X, Y);}/* Functions for playing a game -------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -