📄 player.cpp
字号:
} handtile_t *p[3] = {NULL, NULL, NULL}, *pt; int count = 0, j; for (j = 0; j < m_Hand.m_iNumTiles; j++) { if (m_Hand.m_Tiles[j].tileset == i) { assert(count < 3); p[count++] = &m_Hand.m_Tiles[j]; } } assert(count >= 2); if (count == 2) { fu += 2; } else if (m_Hand.m_TileSets[i].type & HT_CLOSEDCHOW) { for (j = 0; j < count; j++) { if (p[j]->flags & HT_JUSTGOT) { pt = p[0]; p[0] = p[j]; p[j] = pt; break; } } if (p[1]->tile > p[2]->tile) { pt = p[1]; p[1] = p[2]; p[2] = pt; } if (p[0]->tile() == p[1]->tile() + 1 && p[0]->tile() == p[2]->tile() - 1) { fu += 2; } else { if ((p[0]->tile.GetValue() == 3 && p[1]->tile.GetValue() == 1) || (p[0]->tile.GetValue() == 7 && p[1]->tile.GetValue() == 8)) { fu += 2; } } } } } m_Result.selfdrawn = false; if (fu == 20) { if (m_Result.concealed) { m_Result.pinfu = 1; m_Result.fu = (ron ? 30 : 20); if (!ron) { m_Result.selfdrawn = true; } return; } } if (!ron) { fu += 2; m_Result.selfdrawn = true; } else if (m_Result.concealed) { fu += 10; } if (fu <= 20 && HasFan() <= 1) { fu = 30; } m_Result.fu = (fu + 9) / 10 * 10;}void CBasePlayer::CalcScore(){ int fan = HasFan(); if (HasYakuman() || fan >= 13) { m_Result.score = 8000; m_Result.level = SL_YAKUMAN; } else if (fan == 5) { m_Result.score = 2000; m_Result.level = SL_MANGAN; } else if (fan >= 6 && fan <= 7) { m_Result.score = 3000; m_Result.level = SL_HANEMAN; } else if (fan >= 8 && fan <= 10) { m_Result.score = 4000; m_Result.level = SL_BAIMAN; } else if (fan >= 11) { m_Result.score = 6000; m_Result.level = SL_SANBAIMAN; } else { int n = 4, i; for (i = 0; i < fan; i++) { n *= 2; } m_Result.score = m_Result.fu * n; if (m_Result.score >= 2000) { m_Result.score = 2000; m_Result.level = SL_MANGAN; } else { switch (fan) { case 0: case 1: m_Result.level = SL_ONEHAN; break; case 2: m_Result.level = SL_TWOHAN; break; case 3: m_Result.level = SL_THREEHAN; break; case 4: m_Result.level = SL_FOURHAN; break; default: assert(false); break; } } } if (m_iTurn == TURN_EAST) { m_Result.score *= 6; } else { m_Result.score *= 4; } m_Result.score += gpGame->GetNumDeal() * 100; // round it up to the nearest hundred m_Result.score = (m_Result.score + 99) / 100 * 100;}bool CBasePlayer::ActionIsValid(enum actionstate state, playeraction act){ int i; switch (state) { case AS_DRAW: switch (act) { case PA_DRAW: return true; case PA_DISCARD: return false; case PA_PUNG: if (m_fReach || (m_iState & PS_ASKED) || m_iNumDiscarded >= 20) return false; return m_Hand.CanPung(m_pOpponent->LastDiscardedTile()); case PA_CHOW: if (m_fReach || (m_iState & PS_ASKED) || m_iNumDiscarded >= 20) return false; return (m_Hand.CanChow(m_pOpponent->LastDiscardedTile(), CHOW_UPPER) || m_Hand.CanChow(m_pOpponent->LastDiscardedTile(), CHOW_MIDDLE) || m_Hand.CanChow(m_pOpponent->LastDiscardedTile(), CHOW_LOWER)); case PA_KONG: if (m_fReach || (m_iState & PS_ASKED) || m_iNumDiscarded >= 20) return false; return m_Hand.CanKong(m_pOpponent->LastDiscardedTile(), true); case PA_REACH: return false; case PA_MAHJONG: { CTile waiting[13]; int i, j, num; num = m_Hand.GetWaitingTile(waiting, 13); if (num <= 0) { return false; // This is not a ready hand at all } if (!m_fTuiDaoHu) { if (num < 13) { for (i = 0; i < m_iNumDiscarded; i++) { for (j = 0; j < num; j++) { if (m_Discarded[i].tile == waiting[j]) { // player has discarded waiting tile return false; } } } } if (m_fReach) { for (i = 0; i < m_pOpponent->m_iNumDiscarded; i++) { if (m_pOpponent->m_Discarded[i].flags & DT_OPPONENTREACH) { break; } } if (i >= m_pOpponent->m_iNumDiscarded) { i = -1; } for (i++; i < m_pOpponent->m_iNumDiscarded - 1; i++) { for (j = 0; j < num; j++) { if (m_pOpponent->m_Discarded[i].tile == waiting[j]) { return false; } } } } } CHand bak = m_Hand; if (m_Hand.GoMahjong(m_pOpponent->LastDiscardedTile())) { CalcResult(); m_Hand = bak; if (m_fTuiDaoHu || HasFan() - m_Result.dora > 0) { return true; } } return false; } default: return false; } break; case AS_DISCARD: switch (act) { case PA_DRAW: return false; case PA_DISCARD: return true; case PA_PUNG: return false; case PA_CHOW: return false; case PA_KONG: for (i = m_Hand.m_iNumTiles - 1; i >= 0; i--) { if (m_Hand.m_Tiles[i].flags & HT_OPEN) { continue; } if (m_Hand.CanKong(m_Hand.m_Tiles[i].tile, false)) { return true; } if (m_fReach) { break; } } return false; case PA_REACH: if (m_Hand.IsConcealed() && !m_fReach && m_iNumDiscarded < 19 && m_pOpponent->m_iNumDiscarded < 20) { for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_LOCKED) { continue; } CHand t = m_Hand; t.RemoveTile(i); if (t.IsReady()) { return true; } } } return false; case PA_MAHJONG: if (m_Hand.GoMahjong()) { CalcResult(); m_Hand.Restore(); if (m_fTuiDaoHu || HasFan() - m_Result.dora > 0) { return true; } } return false; default: return false; } break; } return false;}bool CBasePlayer::IsRoundDraw(){ return (m_iNumDiscarded >= 20 || (!gpGame->CanDeclareKong() && !(m_iState & PS_KONGED)));}void CBasePlayer::DrawResult(){ const char *res[] = { msg("1han"), msg("2han"), msg("3han"), msg("4han"), msg("man"), msg("hane"), msg("bai"), msg("3bai"), msg("yaku") }; int top = 10, y; if (IsBot()) { top += 85; } y = top;#define DRAW_FAN(name, fan, fanc) \ { \ if (m_Result.name) { \ gpGeneral->DrawUTF8Text(msg(#name), 20, y, 0, 255, 255, 0); \ if (fan < 13) { \ gpGeneral->DrawUTF8Text(va(msg("num_fan"), \ (m_Result.concealed ? fanc : fan) * m_Result.name), \ 175, y); \ } \ y += 32; \ } \ } DRAW_FAN(tenhou, 13, 13); DRAW_FAN(renhou, 13, 13); DRAW_FAN(chihou, 13, 13); DRAW_FAN(tuisou, 13, 13); DRAW_FAN(chinraotou, 13, 13); DRAW_FAN(ryuisou, 13, 13); DRAW_FAN(daisangen, 13, 13); DRAW_FAN(daisusi, 13, 13); DRAW_FAN(syosusi, 13, 13); DRAW_FAN(suankou, 13, 13); DRAW_FAN(surenkou, 13, 13); DRAW_FAN(kokusi, 13, 13); DRAW_FAN(cyurenpotou, 13, 13); DRAW_FAN(sukantu, 13, 13); if (!HasYakuman()) { DRAW_FAN(reach, 0, 1); DRAW_FAN(pinfu, 0, 1); DRAW_FAN(ippatu, 0, 1); DRAW_FAN(double_reach, 0, 1); DRAW_FAN(tanyao, 1, 1); DRAW_FAN(tumo, 0, 1); DRAW_FAN(ryanpeikou, 3, 3); DRAW_FAN(iipeikou, 0, 1); DRAW_FAN(sansiki, 1, 2); DRAW_FAN(sansiki_doukoku, 2, 2); DRAW_FAN(toitoi, 2, 2); DRAW_FAN(sanankou, 2, 2); DRAW_FAN(sanrenkou, 2, 2); DRAW_FAN(junchan, 2, 3); DRAW_FAN(chanta, 1, 2); DRAW_FAN(ittu, 1, 2); DRAW_FAN(chinitu, 5, 6); DRAW_FAN(honitu, 2, 3); DRAW_FAN(chitoitu, 0, 2); DRAW_FAN(honraotou, 2, 2); DRAW_FAN(syosangen, 2, 2); DRAW_FAN(haitei, 1, 1); DRAW_FAN(houtei, 1, 1); DRAW_FAN(rinshan, 1, 1); DRAW_FAN(fanpai, 1, 1); DRAW_FAN(dora, 1, 1); DRAW_FAN(sankantu, 2, 2); DRAW_FAN(nofan, 1, 1); } if (!HasFan()) { gpGeneral->DrawUTF8Text(msg("nofan"), 20, y, 0, 255, 255, 0); } y = top; if (!HasYakuman()) { gpGeneral->DrawUTF8Text(msg("total"), 420, y, 0, 255, 255, 0); y += 32; gpGeneral->DrawUTF8Text(va(msg("num_fu_fan"), m_Result.fu, HasFan()), 420, y); y += 40; } gpGeneral->DrawUTF8Text(res[m_Result.level], 420, y, 0, 255, 255, 0); y += 40; gpGeneral->DrawUTF8Text(va(msg("num_score"), m_Result.score), 420, y, 0, 0, 0, 255); gpGeneral->UpdateScreen();}int CBasePlayer::IndexToLoc(int index){ int loc = 0, i; if (index < 0 || index >= m_Hand.m_iNumTiles) return -1; // this isn't a valid index for (i = 0; i < m_Hand.m_iNumTileSets; i++) { if ((m_Hand.m_TileSets[i].type & HT_OPEN) && !(m_Hand.m_TileSets[i].type & HT_RON)) loc += 3; } for (i = 0; i < m_Hand.m_iNumTiles; i++) { if ((m_Hand.m_Tiles[i].flags & HT_OPEN) && !(m_Hand.m_Tiles[i].flags & HT_RON)) continue; if (i == index) return loc; loc++; } return loc;}//---------------------------------------------------------------#define DRAW_LOCATION(l) \ (((l) >= 13) ? (20 + TILE_WIDTH * (l) + 8) : (20 + TILE_WIDTH * (l)))CPlayer::CPlayer(){ m_fAutoDraw = (atoi(cfg.Get("GAME", "AutoDraw", "0")) > 0);}CPlayer::~CPlayer(){}void CPlayer::NewRound(){ m_iNumSanGenRush = 0; CBasePlayer::NewRound();}// Draw the player's handvoid CPlayer::DrawHand(bool shown){ int i, j, loc = 0; char c[2] = "A"; for (i = 0; i < m_Hand.m_iNumTileSets; i++) { if ((m_Hand.m_TileSets[i].type & HT_OPEN) && !(m_Hand.m_TileSets[i].type & HT_RON)) { if (m_Hand.m_TileSets[i].type & HT_OPENKONG) { for (j = 0; j < 3; j++) { gpGeneral->EraseArea(DRAW_LOCATION(loc), 380, TILE_WIDTH, 100); gpGeneral->DrawTile(m_Hand.m_TileSets[i].first, DRAW_LOCATION(loc), 410, PLAYER_SHOWN); loc++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -