📄 player.cpp
字号:
act++; if (act >= PA_COUNT) { act = PA_NONE + 1; } } while (!ActionIsValid(AS_DISCARD, (playeraction)act)); } break; case SDLK_DOWN: case SDLK_KP2: case SDLK_LEFT: if (!reach) { do { act--; if (act <= PA_NONE) { act = PA_COUNT - 1; } } while (!ActionIsValid(AS_DISCARD, (playeraction)act)); } break; case SDLK_SPACE: case SDLK_RETURN: case SDLK_KP_ENTER: switch (act) { case PA_DISCARD: index = KeyToIndex(SDLK_n); m_Discarded[m_iNumDiscarded].tile = m_Hand.m_Tiles[index].tile; m_Discarded[m_iNumDiscarded].flags = 0; m_iNumDiscarded++; m_Hand.RemoveTile(index); m_Hand.Sort(); for (index = 0; index < m_Hand.m_iNumTiles; index++) { m_Hand.m_Tiles[index].flags &= ~HT_JUSTGOT; } if (reach && m_Hand.IsReady()) { m_fReach = true; m_Discarded[m_iNumDiscarded - 1].flags |= DT_REACH; if (m_pOpponent->m_iNumDiscarded > 0) { m_pOpponent->m_Discarded[m_pOpponent->m_iNumDiscarded - 1].flags |= DT_OPPONENTREACH; } m_iState = PS_CALLREACH; return PA_REACH; } m_iState = 0; return PA_DISCARD; case PA_REACH: reach = true; gpGeneral->PlaySound(SND_REACH); gpGeneral->DrawDotBar(445, 270, true); gpGeneral->UpdateScreen(445, 270, 20, 85); break; case PA_KONG: if (!reach) { if (ActionKong() != PA_NONE) { m_iState |= PS_KONGED; return PA_KONG; } } break; case PA_MAHJONG: if (!reach) { return PA_MAHJONG; } break; } break; default: if (m_fReach && key != SDLK_n) continue; index = KeyToIndex(key); if (index < 0) { continue; } m_Discarded[m_iNumDiscarded].tile = m_Hand.m_Tiles[index].tile; m_Discarded[m_iNumDiscarded].flags = 0; m_iNumDiscarded++; m_Hand.RemoveTile(index); m_Hand.Sort(); for (index = 0; index < m_Hand.m_iNumTiles; index++) { m_Hand.m_Tiles[index].flags &= ~HT_JUSTGOT; } if (reach && m_Hand.IsReady()) { m_fReach = true; m_Discarded[m_iNumDiscarded - 1].flags |= DT_REACH; if (m_pOpponent->m_iNumDiscarded > 0) { m_pOpponent->m_Discarded[m_pOpponent->m_iNumDiscarded - 1].flags |= DT_OPPONENTREACH; } m_iState = PS_CALLREACH; return PA_REACH; } m_iState = 0; return PA_DISCARD; } } return PA_NONE;}playeraction CPlayer::ActionChow(){ int index[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}}, count = 0, i, j, l = -1; CTile t = m_pOpponent->LastDiscardedTile(), to_find[2]; for (i = CHOW_LOWER; i <= CHOW_UPPER; i++) { switch (i) { case CHOW_LOWER: if (t.GetValue() > 7) continue; to_find[0] = t() + 1; to_find[1] = t() + 2; break; case CHOW_MIDDLE: if (t.GetValue() == 1 || t.GetValue() == 9) continue; to_find[0] = t() - 1; to_find[1] = t() + 1; break; case CHOW_UPPER: if (t.GetValue() < 3) continue; to_find[0] = t() - 1; to_find[1] = t() - 2; break; default: TerminateOnError("CPlayer::ActionChow(): Invalid location"); } for (j = 0; j < m_Hand.m_iNumTiles; j++) { if (m_Hand.m_Tiles[j].flags & HT_LOCKED) { continue; } if (m_Hand.m_Tiles[j].tile == to_find[0]) { index[i][0] = j; } if (m_Hand.m_Tiles[j].tile == to_find[1]) { index[i][1] = j; } } if (index[i][0] != -1 && index[i][1] != -1) { count++; l = i; } else { index[i][0] = -1; } } if (count <= 0) { return PA_NONE; } else if (count == 1) { assert(l != -1); if (m_Hand.Chow(t, l)) { m_pOpponent->m_iNumDiscarded--; m_iState |= PS_ASKED; return PA_CHOW; } } else { l = CHOW_UPPER; while (1) { if (index[l][0] == -1) { l++; if (l > CHOW_UPPER) { l = CHOW_LOWER; } continue; } int loc[2] = {IndexToLoc(index[l][0]), IndexToLoc(index[l][1])}; SDL_Rect dstrect; DrawHand(); dstrect.x = DRAW_LOCATION(loc[0]) + 5; dstrect.y = 382; dstrect.w = TILE_WIDTH - 10; dstrect.h = 10; if (SDL_MUSTLOCK(gpScreen)) { SDL_LockSurface(gpScreen); } SDL_FillRect(gpScreen, &dstrect, SDL_MapRGB(gpScreen->format, 255, 0, 0)); dstrect.x = DRAW_LOCATION(loc[1]) + 5; SDL_FillRect(gpScreen, &dstrect, SDL_MapRGB(gpScreen->format, 255, 0, 0)); if (SDL_MUSTLOCK(gpScreen)) { SDL_UnlockSurface(gpScreen); } gpGeneral->UpdateScreen(0, 380, 640, 100); SDLKey key = gpGeneral->ReadKey(); switch (key) { case SDLK_DOWN: case SDLK_KP2: case SDLK_LEFT: do { l++; if (l > CHOW_UPPER) { l = CHOW_LOWER; } } while (index[l][0] == -1); break; case SDLK_UP: case SDLK_KP8: case SDLK_RIGHT: do { l--; if (l < CHOW_LOWER) { l = CHOW_UPPER; } } while (index[l][0] == -1); break; case SDLK_SPACE: case SDLK_RETURN: case SDLK_KP_ENTER: if (m_Hand.Chow(t, l)) { m_pOpponent->m_iNumDiscarded--; m_iState |= PS_ASKED; return PA_CHOW; } break; default: i = KeyToIndex(key); if (i >= 0 && i < m_Hand.m_iNumTiles) { if (m_Hand.m_Tiles[i].flags & HT_OPEN) { break; } for (j = 0; j < count; j++) { if (m_Hand.m_Tiles[index[j][0]].tile == m_Hand.m_Tiles[i].tile || m_Hand.m_Tiles[index[j][1]].tile == m_Hand.m_Tiles[i].tile) { l = j; break; } } } break; } } } return PA_NONE;}playeraction CPlayer::ActionKong(){ int count = 0, i, l = -1; for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_OPEN) { continue; } if (m_Hand.CanKong(m_Hand.m_Tiles[i].tile, false)) { count++; l = i; } } if (count <= 0) { return PA_NONE; } else if (count <= 4) { assert(l != -1); if (m_Hand.Kong(m_Hand.m_Tiles[l].tile, false)) { m_iState |= PS_KONGED; return PA_KONG; } } else { assert(l != -1); while (1) { int loc = IndexToLoc(l); SDL_Rect dstrect; DrawHand(); dstrect.x = DRAW_LOCATION(loc) + 5; dstrect.y = 382; dstrect.w = TILE_WIDTH - 10; dstrect.h = 10; if (SDL_MUSTLOCK(gpScreen)) { SDL_LockSurface(gpScreen); } SDL_FillRect(gpScreen, &dstrect, SDL_MapRGB(gpScreen->format, 255, 0, 0)); if (SDL_MUSTLOCK(gpScreen)) { SDL_UnlockSurface(gpScreen); } gpGeneral->UpdateScreen(0, 380, 640, 100); SDLKey key = gpGeneral->ReadKey(); switch (key) { case SDLK_UP: case SDLK_KP8: case SDLK_RIGHT: do { l++; if (l >= m_Hand.m_iNumTiles) { l = 0; } } while (!m_Hand.CanKong(m_Hand.m_Tiles[l].tile, false)); break; case SDLK_DOWN: case SDLK_KP2: case SDLK_LEFT: do { l--; if (l < 0) { l = m_Hand.m_iNumTiles - 1; } } while (!m_Hand.CanKong(m_Hand.m_Tiles[l].tile, false)); break; case SDLK_SPACE: case SDLK_RETURN: case SDLK_KP_ENTER: if (m_Hand.Kong(m_Hand.m_Tiles[l].tile, false)) { m_iState |= PS_KONGED; return PA_KONG; } break; default: i = KeyToIndex(key); if (i < 0 || i >= m_Hand.m_iNumTiles) { break; } if (m_Hand.m_Tiles[i].flags & HT_OPEN) { break; } if (m_Hand.CanKong(m_Hand.m_Tiles[i].tile, false)) { l = i; } break; } } } return PA_NONE;}void CPlayer::DrawAction(playeraction act){ gpGeneral->EraseArea(580, 330, 50, 28); const char *pStr = NULL; switch (act) { case PA_DRAW: pStr = msg("player_drawtile"); break; case PA_DISCARD: pStr = msg("player_discardtile"); break; case PA_PUNG: pStr = msg("player_pung"); break; case PA_CHOW: pStr = msg("player_chow"); break; case PA_KONG: pStr = msg("player_kong"); break; case PA_REACH: pStr = msg("player_reach"); break; case PA_MAHJONG: pStr = msg("player_gomahjong"); break; } if (pStr == NULL) { gpGeneral->UpdateScreen(580, 330, 50, 28); return; // do nothing } gpGeneral->DrawUTF8Text(pStr, 580, 330, 0, 255, 255, 100); gpGeneral->UpdateScreen(580, 330, 50, 28);}void CPlayer::SanGenInit(){ int i, j; CTile sangen[3] = {"RD", "GD", "WD"}; m_iNumSanGenRush = RandomLong(2, 3) * 3; for (i = 0; i < m_iNumSanGenRush / 3; i++) { for (j = 0; j < 3; j++) { CTile::FetchTile(sangen[i]); m_SanGenRush[i * 3 + j] = sangen[i]; } } m_iCountSanGenRush = RandomLong(2, 7);}bool CPlayer::SanGenRush(){ SDLKey key; int index, changed = 0, num = 0; gpGeneral->DrawMessage(msg("sangenrush")); gpGeneral->PlaySound(SND_SOUND2); do { key = gpGeneral->ReadKey(); index = KeyToIndex(key); if (index < 0 || index >= 13 || (changed & (1 << index))) continue; changed |= (1 << index); CTile::ReturnTile(m_Hand.m_Tiles[index].tile); m_Hand.m_Tiles[index].tile = m_SanGenRush[m_iNumSanGenRush - 1]; num++; gpGeneral->PlaySound(SND_SOUND3); gpGeneral->EraseArea(DRAW_LOCATION(index), 380, TILE_WIDTH, TILE_HEIGHT_CONCEALED); gpGeneral->DrawTile(m_Hand.m_Tiles[index].tile, DRAW_LOCATION(index), 396, WALL_CONCEALED); gpGeneral->UpdateScreen(DRAW_LOCATION(index), 380, TILE_WIDTH, TILE_HEIGHT_CONCEALED); } while (key != SDLK_RETURN && num < 3); UTIL_Delay(200); gpGeneral->DrawMessage(NULL); gpGeneral->PlaySound(SND_SOUND2); DrawHand(); gpGeneral->UpdateScreen(0, 380, 640, 100); return (num > 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -