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

📄 tile.cpp

📁 上面上传的autotools一文(也就是《使用GNU autotools 改造一个软件项目》)配套的示例程序源代码。
💻 CPP
字号:
//
// Copyright (c) 2005, Wei Mingzhi <whistler@openoffice.org>
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301, USA
//

#include "main.h"

static int RemainTiles[5][9];

int CTile::GetSuit() const
{
   int suit = GetKind();
   for (int i = 0; i < 4; i++) {
      suit &= ~(1 << i);
   }
   return suit;
}

int CTile::GetValue() const
{
   return m_iKind & ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));
}

// Given a tile, return its two letter string. The string must be// in static storage and immutable.
const char *CTile::GetCode() const
{
   // two letter codes for tiles   static char *chartiles[] = {"1C", "2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C"};   static char *dottiles[] = {"1D", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D"};   static char *bamtiles[] = {"1B", "2B", "3B", "4B", "5B", "6B", "7B", "8B", "9B"};

   if (GetSuit() == TILESUIT_CHAR) {
      return chartiles[GetValue() - 1];
   } else if (GetSuit() == TILESUIT_BAMBOO) {
      return bamtiles[GetValue() - 1];
   } else if (GetSuit() == TILESUIT_CIRCLE) {
      return dottiles[GetValue() - 1];
   } else if (GetSuit() == TILESUIT_WIND) {
      switch (GetValue()) {
         case EASTWIND:   return "EW";
         case SOUTHWIND:  return "SW";
         case WESTWIND:   return "WW";
         case NORTHWIND:  return "NW";
      }
   } else if (GetSuit() == TILESUIT_DRAGON) {
      switch (GetValue()) {
         case REDDRAGON:    return "RD";
         case GREENDRAGON:  return "GD";
         case WHITEDRAGON:  return "WD";
      }
   }

   TerminateOnError("CTile::GetCode() error: %i", m_iKind);
   return "XX";
}

void CTile::SetKind(const char *code)
{
   if (code[0] >= '0' && code[0] <= '9') {
      m_iKind = code[0] - '0';
      switch (code[1]) {
         case 'B':
         case 'b':
            m_iKind |= TILESUIT_BAMBOO;
            break;

         case 'C':
         case 'c':
            m_iKind |= TILESUIT_CHAR;
            break;

         case 'D':
         case 'd':
            m_iKind |= TILESUIT_CIRCLE;
            break;

         default:
            TerminateOnError("CTile::SetKind() error #1: %s", code);
            break;
      }
   } else {
      if (code[1] == 'w' || code[1] == 'W') {
         switch (code[0]) {
            case 'E':
            case 'e':
               m_iKind = EASTWIND;
               break;

            case 'S':
            case 's':
               m_iKind = SOUTHWIND;
               break;

            case 'W':
            case 'w':
               m_iKind = WESTWIND;
               break;

            case 'N':
            case 'n':
               m_iKind = NORTHWIND;
               break;

            default:
               TerminateOnError("CTile::SetKind() error #2: %s", code);
               break;
         }
         m_iKind |= TILESUIT_WIND;
      } else if (code[1] == 'd' || code[1] == 'D') {
         switch (code[0]) {
            case 'R':
            case 'r':
               m_iKind = REDDRAGON;
               break;

            case 'G':
            case 'g':
               m_iKind = GREENDRAGON;
               break;

            case 'W':
            case 'w':
               m_iKind = WHITEDRAGON;
               break;

            default:
               TerminateOnError("CTile::SetKind() error #3: %s", code);
               break;
         }
         m_iKind |= TILESUIT_DRAGON;
      } else {
         TerminateOnError("CTile::SetKind() error #4: %s", code);
      }
   }
}

CTile CTile::Dora() const
{
   if (GetSuit() == TILESUIT_DRAGON) {
      switch (GetValue()) {
         case REDDRAGON:
            return CTile(GetSuit() | WHITEDRAGON);

         case WHITEDRAGON:
            return CTile(GetSuit() | GREENDRAGON);

         case GREENDRAGON:
            return CTile(GetSuit() | REDDRAGON);
      }
   } else {
      int v = GetValue() + 1;
      if (v > 9 || (GetSuit() == TILESUIT_WIND && v > 4))
         v = 1;
      return CTile(GetSuit() | v);
   }

   TerminateOnError("CTile::Dora(): Invalid tile!");
   return CTile("1C"); // to remove the compiler warning
}

void CTile::NewRound()
{
   int i, j;

   for (i = 0; i < 5; i++) {
      for (j = 0; j < 9; j++) {
         RemainTiles[i][j] = 4;
      }
   }

   // we only have 4 kinds of winds and 3 kinds of dragons
   for (i = 4; i < 9; i++) {
      RemainTiles[3][i] = 0;
   }
   for (i = 3; i < 9; i++) {
      RemainTiles[4][i] = 0;
   }
}

CTile CTile::RandomTile()
{
   CTile wall[172];
   int num = 0;

   // Push all possible tiles to the wall
   for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 9; j++) {
         for (int k = 0; k < RemainTiles[i][j]; k++) {
            int suit = ((1 << 4) << i);
            int value = j + 1;
            assert((suit + value) == (suit | value));
            wall[num++] = CTile(suit | value);
         }
      }
   }

   // pick a random one in the wall
   if (num <= 0) {
      // can this ever happen if nothing messed up?
      TerminateOnError("CTile::RandomTile(): No tile left!");
   }

   CTile &got = wall[RandomLong(0, num - 1)];
   RemainTiles[got.index1()][got.index2()] -= 1;

   return got;
}

int CTile::RemainingTile(const CTile &t)
{
   return RemainTiles[t.index1()][t.index2()];
}

bool CTile::FetchTile(const CTile &t)
{
   if (RemainTiles[t.index1()][t.index2()] <= 0)
      return false; // No this tile left
   RemainTiles[t.index1()][t.index2()] -= 1;
   return true;
}

void CTile::ReturnTile(const CTile &t)
{
   RemainTiles[t.index1()][t.index2()] += 1;
}

⌨️ 快捷键说明

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