⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reversi.c

📁 ucgui3.90a
💻 C
📖 第 1 页 / 共 4 页
字号:
  WM_HWIN hFrame, hClient, hItem;
  /* Create framewin */
  hFrame = FRAMEWIN_CreateEx(70, 75, 180, 90, WM_HBKWIN, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Game settings", &_cbDialogSettings);
  FRAMEWIN_SetClientColor   (hFrame, GUI_WHITE);
  FRAMEWIN_SetFont          (hFrame, &GUI_Font10_1);
  FRAMEWIN_SetTextAlign     (hFrame, GUI_TA_HCENTER);
  /* Create dialog items */
  hClient = WM_GetClientWindow(hFrame);
  /* Create button */
  hItem = BUTTON_CreateEx(59, 46, 55, 18, hClient, WM_CF_SHOW, 0, GUI_ID_OK);
  BUTTON_SetText         (hItem, "Ok");
  /* Create checkbox */
  hItem = CHECKBOX_CreateEx(10, 10, 140, 0, hClient, WM_CF_SHOW, 0, GUI_ID_CHECK0);
  CHECKBOX_SetText         (hItem, "Show possible moves");
  CHECKBOX_SetBkColor      (hItem, GUI_INVALID_COLOR);
  CHECKBOX_SetState        (hItem, _ShowPossibleMoves);
  /* Exec modal dialog */
  WM_SetFocus(hFrame);
  WM_MakeModal(hFrame);
  GUI_ExecCreatedDialog(hFrame);
  WM_SetFocus(_hFrame);
}

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/
/*******************************************************************
*
*       _DoDirection
*/
static void _DoDirection(int x, int y, int dx, int dy) {
  do {
    _SetStone(x, y);
    x += dx;
    y += dy;
  } while (_GetStone(x, y) != _ActPlayer);
}

/*******************************************************************
*
*       _MakeMove
*/
static void _MakeMove(int x, int y) {
  U16 Cell;
  _SetStone(x, y);
  _Delay(150);
  Cell = _Board[x][y];
  if (Cell & (U16)(1 <<  8)) { _DoDirection(x, y, -1, -1); }
  if (Cell & (U16)(1 <<  9)) { _DoDirection(x, y,  0, -1); }
  if (Cell & (U16)(1 << 10)) { _DoDirection(x, y,  1, -1); }
  if (Cell & (U16)(1 << 11)) { _DoDirection(x, y,  1,  0); }
  if (Cell & (U16)(1 << 12)) { _DoDirection(x, y,  1,  1); }
  if (Cell & (U16)(1 << 13)) { _DoDirection(x, y,  0,  1); }
  if (Cell & (U16)(1 << 14)) { _DoDirection(x, y, -1,  1); }
  if (Cell & (U16)(1 << 15)) { _DoDirection(x, y, -1,  0); }
}

/*******************************************************************
*
*       _CalcScore
*/
static int _CalcScore(void) {
  int x, y, r = 0;
  U16 Cell;
  for (y = 0; y < 8; y++) {
    for (x = 0; x < 8; x++) {
      Cell = (_Board[x][y] & 0xFF);
      if (Cell) {
        r += (Cell == 1) ? (1) : (-1);
      }
    }
  }
  return r;
}

/*******************************************************************
*
*       _CheckDirection
*/
static char _CheckDirection(int x, int y, int dx, int dy) {
  char Cell = 0;
  x += dx;
  y += dy;
  if (_GetStone(x, y) == (3 - _ActPlayer)) {
    do {
      x += dx;
      y += dy;
      Cell = _GetStone(x, y);
    } while (Cell == (3 - _ActPlayer));
  }
  return ((Cell == _ActPlayer) ? 1 : 0);
}

/*******************************************************************
*
*       _CalcValidMoves
*/
static int _CalcValidMoves(void) {
  int x, y, r = 0;
  U16 Cell;
  for (y = 0; y < 8; y++) {
    for (x = 0; x < 8; x++) {
      Cell = _Board[x][y] & 0xFF;
      if (Cell == 0) {
        Cell |= _CheckDirection(x, y, -1, -1) <<  8;
        Cell |= _CheckDirection(x, y,  0, -1) <<  9;
        Cell |= _CheckDirection(x, y,  1, -1) << 10;
        Cell |= _CheckDirection(x, y,  1,  0) << 11;
        Cell |= _CheckDirection(x, y,  1,  1) << 12;
        Cell |= _CheckDirection(x, y,  0,  1) << 13;
        Cell |= _CheckDirection(x, y, -1,  1) << 14;
        Cell |= _CheckDirection(x, y, -1,  0) << 15;
        if (Cell) {
          r++;
        }
      }
      if (Cell != _Board[x][y]) {
        _Board[x][y] = Cell;
        _InvalidateCell(x, y);
      }
    }
  }
  return r;
}

/*******************************************************************
*
*       _SetPlayer
*/
static void _SetPlayer(int Player) {
  int PossibleMoves;
  _ActPlayer = Player;
  if (Player == 1) {
    FRAMEWIN_SetText(_hFrame, "Reversi - Player 1");
  } else {
    FRAMEWIN_SetText(_hFrame, "Reversi - Player 2");
  }
  FRAMEWIN_SetBarColor(_hFrame, 1, (Player == 1) ? GUI_RED : GUI_BLUE);
  PossibleMoves = _CalcValidMoves();
  GUI_Exec();

  if (!PossibleMoves) {
    int ValidMoves;
    GUI_Exec();
    _ActPlayer = 3 - Player;
    ValidMoves = _CalcValidMoves();
    _ActPlayer = Player;
    _CalcValidMoves();
    if (ValidMoves) {   /* No valid moves, player must pass */
      if (_pPlayerAI[_ActPlayer - 1] == NULL) {
        _ShowMessageBox("Reversi", "No possible moves.\nYou have to pass!", 0);
      } else {
        /* Pass ai player */
      }
      _SetPlayer(3 - _ActPlayer);
    } else {            /* No valid moves for all players, game is over */
      char ac[256];
      int Score;
      _GameOver = 1;
      Score = _CalcScore();
      if (Score > 0) {
        sprintf(ac, "Red wins by %d stones!\nDo you want to start a new game?", Score);
      } else if (Score) {
        sprintf(ac, "Blue wins by %d stones!\nDo you want to start a new game?", -Score);
      } else {
        strcpy(ac, "The game ends in a draw!\nDo you want to start a new game?");
      }
      if (_ShowMessageBox("Reversi", ac, 1)) {
        _StartNewGame();
      }
    }
  }
}

/*******************************************************************
*
*       _NextPlayer
*/
static void _NextPlayer(void) {
  do {
    _SetPlayer(3 - _ActPlayer);
    if (_pPlayerAI[_ActPlayer - 1]&& !_GameOver) {
      int x, y;
      char DoMove;
      DoMove = (*_pPlayerAI[_ActPlayer - 1])(_Board, 0, _ActPlayer, &x, &y);
      _Delay(150);
      if (DoMove) {
        _MakeMove(x, y);
      }
    }
  } while (_pPlayerAI[_ActPlayer - 1] && !_GameOver);
}

/*******************************************************************
*
*       _StartNewGame
*/
static void _StartNewGame(void) {
  memset(_Board, 0, sizeof(_Board));
  _Board[3][3] = 1;
  _Board[4][4] = 1;
  _Board[3][4] = 2;
  _Board[4][3] = 2;
  _GameOver    = 0;
  _SetPlayer(1);
  _InvalidateBoard();
}

/*******************************************************************
*
*       _HandlePID
*/
static void _HandlePID(int x, int y, int Pressed) {
  static int _IsInHandlePID = 0;
  if (_IsInHandlePID++ == 0) {
    _CalcBoardDimensions();
    x -= _BoardX0;
    y -= _BoardY0;
    if ((x >= 0) && (y >= 0)) {
      x /= _CellSize;
      y /= _CellSize;
      if ((x < 8) && (y < 8)) {
        if (_IsValidMove(x, y)) {
          if (Pressed == 0) {
            _ReleaseCapture();
            _MakeMove(x, y);
            _NextPlayer();
          } else {
            _SetCapture();
          }
          goto EndHandlePID;
        }   
      }
    }
    _ReleaseCapture();
  }
EndHandlePID:
  _IsInHandlePID--;
}

/*********************************************************************
*
*       _OnTouch
*/
static void _OnTouch(WM_MESSAGE* pMsg) {
  const GUI_PID_STATE* pState = (const GUI_PID_STATE*)pMsg->Data.p;
  if (pState) {  /* Something happened in our area (pressed or released) */
    _HandlePID(pState->x, pState->y, pState->Pressed);
  }
}

/*********************************************************************
*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -