[ create a new paste ] login | about

Link: http://codepad.org/qp8JCPVT    [ raw code | output | fork ]

mohit_at_codepad - C++, pasted on Jul 9:
// Original problem statement @ http://nabetani.sakura.ne.jp/hena/1/
// Input is game steps for tic tac toe
// o takes the first move. Moves keep alternating between o and x then onwards
// If o or x makes a line of 3 in any direction, it is declared as won
// It o or x makes a move over already marked block, it is declared as foul
// and opponent is declared as winner
// Input is never broken. So you don't need to handle the exception case.
//  1 | 2 | 3
//  --+---+--
//  4 | 5 | 6           <---------     Board layout
//  --+---+--
//  7 | 8 | 9

#include <iostream>
#include <cctype>
#include <cassert>
using namespace std;

class CTicTacToe {
  static const signed char BAD_INPUT_ = 'B';
  static const signed char CONTINUE_  = 'C';
  static const signed char DRAW_GAME_ = 'D';
public:
  CTicTacToe()
      : firstMover('o')
      , curMover('o')      //curMover(firstMover)
      , status(CONTINUE_)
      , nMoves(0) {
    for(int i = 0; i < 3; ++i)
    for(int j = 0; j < 3; ++j)
      board[i][j] = '.';
  }

  bool isRemaining() const { return getStatus() == CONTINUE_; }
  signed char getStatus() const { return status; }
  void playNext(signed char move);
private:
  void play(int r, int c);
  signed char flipMover(signed char c) const { return 'x' - c + 'o'; }
  bool isCurWinning() const;
  bool hasWon() const;
private:
  // Why char? Because it is easy to debug
  // Tic tac toe is NOT a complex game in terms of space and computation
  // requirement.
  // Why explicitly signed? To make flipMover work.
  signed char firstMover;
  signed char curMover;
  signed char board[3][3];
  signed char status;
  int nMoves;
};

void CTicTacToe::playNext(signed char move) {
  assert(nMoves < 9);    // Bad input case
  assert(status == CONTINUE_);  // Current status of game
  if( '1' <= move && move <= '9') {
    const int n = move - '1';
    const int r = n / 3;
    const int c = n % 3;
    if( board[r][c] == '.' ) {
      play(r, c);
    } else {
      status = toupper( flipMover( curMover ) );
    }
  } else {
    status = BAD_INPUT_;
  }
}

void CTicTacToe::play(int r, int c) {
  if(nMoves++ < 4) {
    board[r][c] = curMover;
  } else {
    board[r][c] = curMover;
    const bool curWon = hasWon();
    if(curWon) {
      status = curMover;
    } else if(9 == nMoves) {
      status = DRAW_GAME_;
    }
  }
  curMover = flipMover( curMover );
}
//
//bool CTicTacToe::isCurWinning() const {
//  for(int i = 0; i < 3; ++i) {
//    int nC = 0, nD = 0;
//    for(int j = 0; j < 3; ++j) {  // Check row#i
//      if(board[i][j] == '.') ++nD;
//      if(board[i][j] == curMover) ++nC;
//    }
//    if(2 == nC && 1 == nD) return true;
//
//    nC = 0, nD = 0;
//    for(int j = 0; j < 3; ++j) {  // Check col#i
//      if(board[j][i] == '.') ++nD;
//      if(board[j][i] == curMover) ++nC;
//    }
//    if(2 == nC && 1 == nD) return true;
//  }
//
//  int nC = 0, nD = 0;
//  for(int j = 0; j < 3; ++j) {  // Check Digonal
//    if(board[j][j] == '.') ++nD;
//    if(board[j][j] == curMover) ++nC;
//  }
//  if(2 == nC && 1 == nD) return true;
//  nC = 0, nD = 0;
//  for(int j = 0; j < 3; ++j) {  // Check Digonal2
//    if(board[j][2-j] == '.') ++nD;
//    if(board[j][2-j] == curMover) ++nC;
//  }
//  if(2 == nC && 1 == nD) return true;
//  return false;
//}

bool CTicTacToe::hasWon() const {
  for(int i = 0; i < 3; ++i) {
    int nC = 0;
    for(int j = 0; j < 3; ++j) {  // Check row#i
      if(board[i][j] == curMover) ++nC;
    }
    if(3 == nC) return true;

    nC = 0;
    for(int j = 0; j < 3; ++j) {  // Check col#i
      if(board[j][i] == curMover) ++nC;
    }
    if(3 == nC) return true;
  }

  int nC = 0;
  for(int j = 0; j < 3; ++j) {  // Check Digonal
    if(board[j][j] == curMover) ++nC;
  }
  if(3 == nC) return true;
  nC = 0;
  for(int j = 0; j < 3; ++j) {  // Check Digonal2
    if(board[j][2-j] == curMover) ++nC;
  }
  if(3 == nC) return true;
  return false;
}

void play(const char *moves) {
  CTicTacToe game;
  int index = 0;
  do {
    //cerr << "Sending move " << moves[index] << endl;
    game.playNext( moves[index++] );
  } while( game.isRemaining() );
  cout << "Input: " << moves << endl;
  switch ( game.getStatus() ) {
    case 'O':
    case 'X':
      cout <<  "Foul : ";
      /* Fall-through */
    case 'o':
    case 'x':
      cout <<  static_cast<char>( tolower( game.getStatus() ) )
          << " won." << endl;
      break;

    case 'D':
      cout << "Draw game." << endl;
      break;

    default:
      cerr << "DEBUG:: " << game.getStatus() << endl;
      cout << "Broken input" << endl;
      break;
  }
  cout << endl;
}

int main(int argc, char *const *argv) {
  for(int i = 1; i < argc; ++i) {
    play(argv[i]);
  }
  if(argc < 2) {
    cout << "Expecting:: x won." << endl;
    play("79538246");
    cout << "Expecting:: x won." << endl;
    play("35497162193");
    cout << "Expecting:: x won." << endl;
    play("61978543");
    cout << "Expecting:: x won." << endl;
    play("254961323121");
    cout << "Expecting:: x won." << endl;
    play("6134278187");

    cout << "-------------------------------------------------" << endl;

    cout << "Expecting:: Foul : x won." << endl;
    play("4319581");
    cout << "Expecting:: Foul : x won." << endl;
    play("9625663381");
    cout << "Expecting:: Foul : x won." << endl;
    play("7975662");
    cout << "Expecting:: Foul : x won." << endl;
    play("2368799597");
    cout << "Expecting:: Foul : x won." << endl;
    play("18652368566");

    cout << "-------------------------------------------------" << endl;

    cout << "Expecting:: o won." << endl;
    play("965715");
    cout << "Expecting:: o won." << endl;
    play("38745796");
    cout << "Expecting:: o won." << endl;
    play("371929");
    cout << "Expecting:: o won." << endl;
    play("758698769");
    cout << "Expecting:: o won." << endl;
    play("42683953");

    cout << "-------------------------------------------------" << endl;

    cout << "Expecting:: Foul : o won." << endl;
    play("618843927");
    cout << "Expecting:: Foul : o won." << endl;
    play("36535224");
    cout << "Expecting:: Foul : o won." << endl;
    play("882973");
    cout << "Expecting:: Foul : o won." << endl;
    play("653675681");
    cout << "Expecting:: Foul : o won." << endl;
    play("9729934662");

    cout << "-------------------------------------------------" << endl;

    cout << "Expecting:: Draw Game." << endl;
    play("972651483927");
    cout << "Expecting:: Draw Game." << endl;
    play("5439126787");
    cout << "Expecting:: Draw Game." << endl;
    play("142583697");
    cout << "Expecting:: Draw Game." << endl;
    play("42198637563");
    cout << "Expecting:: Draw Game." << endl;
    play("657391482");
  }
  return 0;
}

// EOF


Output:
Expecting:: x won.
Input: 79538246
x won.

Expecting:: x won.
Input: 35497162193
x won.

Expecting:: x won.
Input: 61978543
x won.

Expecting:: x won.
Input: 254961323121
x won.

Expecting:: x won.
Input: 6134278187
x won.

-------------------------------------------------
Expecting:: Foul : x won.
Input: 4319581
Foul : x won.

Expecting:: Foul : x won.
Input: 9625663381
Foul : x won.

Expecting:: Foul : x won.
Input: 7975662
Foul : x won.

Expecting:: Foul : x won.
Input: 2368799597
Foul : x won.

Expecting:: Foul : x won.
Input: 18652368566
Foul : x won.

-------------------------------------------------
Expecting:: o won.
Input: 965715
o won.

Expecting:: o won.
Input: 38745796
o won.

Expecting:: o won.
Input: 371929
o won.

Expecting:: o won.
Input: 758698769
o won.

Expecting:: o won.
Input: 42683953
o won.

-------------------------------------------------
Expecting:: Foul : o won.
Input: 618843927
Foul : o won.

Expecting:: Foul : o won.
Input: 36535224
Foul : o won.

Expecting:: Foul : o won.
Input: 882973
Foul : o won.

Expecting:: Foul : o won.
Input: 653675681
Foul : o won.

Expecting:: Foul : o won.
Input: 9729934662
Foul : o won.

-------------------------------------------------
Expecting:: Draw Game.
Input: 972651483927
Draw game.

Expecting:: Draw Game.
Input: 5439126787
Draw game.

Expecting:: Draw Game.
Input: 142583697
Draw game.

Expecting:: Draw Game.
Input: 42198637563
Draw game.

Expecting:: Draw Game.
Input: 657391482
Draw game.



Create a new paste based on this one


Comments: