Next: Java Implementation
Up: Von C++ zu Java
Previous: Ein vergleichendes Beispiel
// Aus: Michael A. Smith, Object-Oriented Software in C++, // Chapman & Hall, London 1995, Seite 98ff #ifndef __FOURINAROW_H__ #define __FOURINAROW_H__ #include <iostream.h> #ifdef FALSE #undef FALSE #endif #ifdef TRUE #undef TRUE #endif const int MAXROW = 9; // Maximun Rows const int MAXCOLUMN = 9; // Maximum Columns enum Boolean {FALSE, TRUE}; enum BoardState {DRAW, WIN, PLAY}; const int STONES_IN_A_WIN_LINE = 4; const int NO_OF_PLAYERS = 2; const int DEF_ROWS = 6; // Default number of rows const int DEF_COLUMNS = 7; // Default number of columns const char INVISIBLE = ' '; const int SELECT_REPRESENTATION = 1; #endif
#ifndef __BOARD_H__ #define __BOARD_H__ #include "FourInaRow.h" #include "Cell.h" class Board { public: Board(const int rows=DEF_ROWS, const int columns=DEF_COLUMNS); void reset(const int rows=DEF_ROWS, const int columns=DEF_COLUMNS); void drop_in_column(const int, const Counter); Boolean move_ok_for_column(const int) const; void display(void) const; BoardState situation(void) const; protected: int check_for_a_win(const int, const int, const int, const char) const; void add_counter_to_board(const int, const Counter); Boolean is_there_a_win(void) const; private: Cell the_grid[MAXROW][MAXCOLUMN]; // Board played on int the_height[MAXCOLUMN]; // Current height of counters col int the_row_size; int the_column_size; // Size of playing area int the_last_col; int the_last_row; // Last counter placed int the_no_empty_cells; // No. of cells still empty }; #endif
#include "Board.h" Board::Board(const int rows, const int columns) { reset(rows, columns); } void Board::reset(const int rows, const int columns) { the_row_size = rows; the_column_size = columns; for (int i=0; i<the_column_size; i++) { for (int j=0; j<the_row_size; j++) { the_grid[j][i].drop(Counter(INVISIBLE)); } the_height[i] = 0; } the_last_row = the_last_col = 0; the_no_empty_cells = rows * columns; } void Board::drop_in_column(const int column, const Counter c) { the_last_col = column; the_last_row = the_height[column]; add_counter_to_board(column, c); } Boolean Board::move_ok_for_column(const int column) const { if (column >= 0 && column < the_column_size) { if (the_height[column] < the_row_size) { return TRUE; } } return FALSE; } void Board::add_counter_to_board(const int column, const Counter players_counter) { the_grid[the_height[column] ][column].drop(players_counter); the_height[column]++; the_no_empty_cells--; } BoardState Board::situation(void) const { if (is_there_a_win() == TRUE) { return WIN; } if (the_no_empty_cells == 0) { return DRAW; } return PLAY; } Boolean Board::is_there_a_win(void) const { char stone = the_grid[the_last_row][the_last_col].holds(); for (int dir=1; dir <= 4; dir++) { int stones_in_a_line = check_for_a_win(dir, the_last_row, the_last_col, stone) + check_for_a_win(dir+4, the_last_row, the_last_col, stone) - 1; if ( stones_in_a_line >= STONES_IN_A_WIN_LINE ) { return TRUE; } } return FALSE; } int Board::check_for_a_win(const int dir, const int x_coord, const int y_coord, const char counter) const { int x = x_coord; int y = y_coord; if ( (x >= 0) && (x < the_row_size) && (y >= 0) && (y < the_column_size) && (the_grid[x][y].holds() == counter) ) { switch(dir) { case 1: y++; break; case 2: x++; y++; break; case 3: x++; break; case 4: x++; y--; break; case 5: y--; break; case 6: x--; y--; break; case 7: x--; break; case 8: x--; y++; break; default: cerr << "internal error 1\n"; } return 1 + check_for_a_win(dir, x, y, counter); } else { return 0; } } void Board::display(void) const { cout << " "; for (int j=1; j<=the_column_size; j++) cout << j << " "; cout << '\n'; for (int i=the_row_size - 1; i>=0; i--) { cout << "| "; for (int j=0; j<the_column_size; j++) { the_grid[i][j].display(); cout << " | "; } cout << '\n'; } for (int k=the_row_size; k>=0; k--) cout << "----"; cout << "-\n\n"; }
#ifndef __CELL_H__ #define __CELL_H__ #include "FourInaRow.h" #include "Counter.h" class Cell { public: Cell(); void clear(void); // Clear the cell void drop(const Counter c); // Drop a counter into the cell char holds(void) const; // Return the counters colour void display(void) const; // Display the contents of a cell private: Counter the_counter; }; #endif
#include "Cell.h" Cell::Cell() { the_counter = Counter(INVISIBLE); } void Cell::clear(void) { the_counter = Counter(INVISIBLE); } void Cell::drop(const Counter c) { the_counter = c; } char Cell::holds(void) const { return the_counter.colour(); } void Cell::display(void) const { the_counter.display(); }
#ifndef __COUNTER_H__ #define __COUNTER_H__ #include "FourInaRow.h" class Counter { public: static void prelude(void); Counter(); Counter(const char); Counter(const int); char colour(void) const; // Returns the colour of a counter void display(void) const; // Display the counter private: static int the_counter_no; // Which colour to allocate next char the_colour; // The colour of the counter }; #endif
#include "Counter.h" int Counter::the_counter_no; void Counter::prelude(void) { the_counter_no = 0; } Counter::Counter() { the_colour = INVISIBLE; } Counter::Counter(const int dummy) { the_colour = "xo*+#"[the_counter_no++]; } Counter::Counter(const char representation) { the_colour = representation; } char Counter::colour(void) const { return the_colour; } void Counter::display(void) const { cout << the_colour; }
// Aus: Michael A. Smith, Object-Oriented Software in C++, // Chapman & Hall, London 1995, Seite 98ff #ifndef __PLAYER_H__ #define __PLAYER_H__ #include "FourInaRow.h" #include "Counter.h" class Player { public: Player(); int get_move(const Boolean) const; // Ask for a move Counter get_counter(void) const; // Get a counter void announce(const BoardState) const; // Announce win/draw private: Counter the_players_counter; }; #endif
#include "Player.h" Player::Player() { the_players_counter = Counter(SELECT_REPRESENTATION); } int Player::get_move(const Boolean first) const { int move; if (first != TRUE) cout << "Error Invalid choice" << "\n"; cout << "Move for player "; cout << the_players_counter.colour() << " is "; cin >> move; return move-1; } Counter Player::get_counter(void) const { return the_players_counter; } void Player::announce(const BoardState what) const { cout << "Player " << the_players_counter.colour(); switch(what) { case WIN: cout << " wins\n"; break; case DRAW: cout << " has filled the board\n"; break; } }
#include "Board.h" #include "Player.h" void play() { Board c_4; // The playing board Player contestant[NO_OF_PLAYERS]; // No of players BoardState state = PLAY; // Contestants can Play int no = 0; // First contestand c_4.display(); // display the board while (state == PLAY) { int move = contestant[no].get_move(TRUE); while(c_4.move_ok_for_column(move) == FALSE) { move = contestant[no].get_move(FALSE); } c_4.drop_in_column(move, contestant[no].get_counter()); c_4.display(); state = c_4.situation(); if (state == PLAY) no = (no+1)%NO_OF_PLAYERS; else contestant[no].announce(state); // The result } } main() { Counter::prelude(); play(); }
# defines CC= g++ CFLAGS= -g -Wall CXX= g++ CXXFLAGS= -g -Wall LD= g++ LIBS= -lm BIN= four # Programs SRC= Board.cc Cell.cc Counter.cc Player.cc main.cc OBJS= Board.o Cell.o Counter.o Player.o main.o all: ${BIN} # dependencies Board.o: Board.cc Board.h FourInaRow.h Cell.o: Cell.cc Cell.h FourInaRow.h Counter.o: Counter.cc Counter.h FourInaRow.h Player.o: Player.cc Player.h FourInaRow.h main.o: main.cc # linking ${BIN}: ${OBJS} ${SRC} ${LD} ${OBJS} -o ${BIN} ${LIBS} clean: rm -f *.o *~ *.bak ${BIN} *.aux *.log *.dvi
© 1997 Gottfried Rudorfer, C++-AG, Lehrveranstaltungen, Abteilung für Angewandte Informatik, Wirtschaftsuniversität Wien, 3/19/1998 |