Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

 
 
Thread Tools Display Modes
Prev Previous Post in Thread   Next Post in Thread Next
Old Dec 9th, 2005, 9:42 PM   #1
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Tic Tac Toe progress

I don't know what happened to the Tic Toe contest (I guess there was not enough interest) but I though I would try working on a Tic Tac Toe game. It currently uses text, but after getting enough experience with Qt, I'd like to try to implement it with a GUI.

It also only uses a random position for the AI, because I haven't developed the AI makeMove() function yet.

Keep in mind, this is the equivalent of a rough draft. I'm sure there are hundreds of improvements.
tic.h

//tic.h -- TicTacToe declarations

#ifndef TICTACTOE_H_
#define TICTACTOE_H_

class Board {
	private:
		static char board[3][3];
		char player;
		char otherPlayer;
		char *checkBoard(int);
	public:
		Board(char,char);
		void reset();
		virtual bool makeMove(int);
		bool checkWin();
		void show() const;
		virtual ~Board(); 
};

/*class CBoard : public Board { //TODO
	public:
		CBoard(char);
		virtual bool makeMove(int);
};*/

#endif

tic.cpp

//tic.cpp -- implementation of class

#include <iostream>
#include "tic.h"

char Board::board[3][3];

Board::Board(char icon, char otherIcon) {
	//std::cout << "constructor called" << std::endl;
	player = icon;
	otherPlayer = otherIcon;
}

/*void Board::set() {
	//std::cout << "set() called" << std::endl;
	if(boardSet == false) {
		//std::cout << "Board being set..." << std::endl;
		for(int x = 0; x < 3; x++)
			for(int y = 0; y < 3; y++)
				Board::board[x][y] = ' ';
	}

	else {
		std::cout << "board previously set" << std::endl;
		std::cout << "use reset() to reset game" << std::endl;
	}

	boardSet = true;
}*/

void Board::reset() {
	for(int x = 0; x < 3; x++)
		for(int y = 0; y < 3; y++)
			Board::board[x][y] = ' ';
}

bool Board::makeMove(int space) {
	//board setup is like that of numpad
	if(space < 1 || space > 9) {
		std::cout << "invalid range!" << std::endl;
		
		return false;
	}

	int x, y; //x-axis, y-axis

	switch(space) {
		case 7:
			x = 0;
			y = 0;
			break;
		case 8:
			x = 1;
			y = 0;
			break;
		case 9:
			x = 2;
			y = 0;
			break;
		case 4:
			x = 0;
			y = 1;
			break;
		case 5:
			x = 1;
			y = 1;
			break;
		case 6:
			x = 2;
			y = 1;
			break;
		case 1:
			x = 0;
			y = 2;
			break;
		case 2:
			x = 1;
			y = 2;
			break;
		case 3:
			x = 2;
			y = 2;
			break;
	}
	
	if((Board::board[x][y] == otherPlayer) || (Board::board[x][y] == player)) //if space is taken...
		return false; //move failed. return false.
	else {
		Board::board[x][y] = player; //otherwise, make move

		return true; //return success
	}
}

char *Board::checkBoard(int part) {
	//0, 1, 2 ==> cols
	//3, 4, 5 ==> rows
	//6, 7 ==> diagonals

	char arr[3];
	char *temp = arr;
	
	int space;
	
	switch(part) {
		//columns
		
		case 0:
		case 1:
		case 2:
			for(int a = 0; a < 3; a++)
				temp[a] = Board::board[part][a];
			break;
		//rows
		case 3:
			space = 0;
			for(int a = 0; a < 3; a++)
				temp[a] = Board::board[a][space];
			break;
		case 4:
			space = 1;
			for(int a = 0; a < 3; a++)
				temp[a] = Board::board[a][space];
			break;
		case 5:
			space = 2;
			for(int a = 0; a < 3; a++)
				temp[a] = Board::board[a][space];
			break;
		//diagonals
		case 6:
			temp[0] = Board::board[0][2];
			temp[1] = Board::board[1][1];
			temp[2] = Board::board[2][0];
			break;
		case 7:
			temp[0] = Board::board[0][0];
			temp[1] = Board::board[1][1];
			temp[2] = Board::board[2][2];
	}

	return temp;
}
		
bool Board::checkWin() {
	int count = 0;
	bool winner = false;
	
	//checking rows
	for(int x = 0; x < 3; x++) { //for each row
		char *row = checkBoard(x);//get the row
		count = 0;
		for(int a = 0; a < 3; a++) //check each space in row
			if(*(row + a) == player) //if space is taken
				count++; //increase count

		if(count == 3) //if all three taken on row...
			winner = true; //set winner to true;
	}
	
	//checking columns
	
	for(int x = 3; x < 6; x++) { //for each column
		char *col = checkBoard(x);
		count = 0; //starting count again
		for(int a = 0; a < 3; a++)
			if(*(col + a) == player) //if space is taken
				count++; //increase count

		if(count == 3)
			winner = true;
	}
	
	//checking diagonals
	count = 0;
	
	char *dia1 = checkBoard(6);
	for(int x = 0; x < 3; x++) {
		if(*(dia1 + x) == player)
			count++;
	}
	if(count == 3)
		winner = true;

	//second diagonal
	count = 0;
	char *dia2 = checkBoard(7);
	for(int x = 0; x < 3; x++)
		if(*(dia2 + x) == player)
			count++;
	if(count == 3)
		winner = true;

	return winner; //returns false if no wine, true if winner
}

void Board::show() const {
	std::cout << "---------";
	for(int a = 0; a < 3; a++) {
		std::cout << std::endl;
		std::cout << "|";
		for(int b = 0; b < 3; b++)
			std::cout << " " <<  Board::board[b][a];
		std::cout.put(' ');
		std::cout << "|";
	}
	std::cout << "\n---------" << std::endl;
}

Board::~Board() {
}

main.cpp

#include "tic.h"
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main() {
	srand(time(0));
		
	Board b1('x', 'o');
	Board b2('o', 'x');

	bool done = false;

	int move;
	while(!done) {
		b1.reset();
		while(1) {
			cout << "Enter space with numpad: ";
			cin >> move;
			
			if(!b1.makeMove(move)) {
				cout << "bad move" << endl;
				continue;
			}

			b1.show();
			
			if(b1.checkWin()) {
				cout << "x wins!" << endl;
				done = true;
				break;
			}

			move = rand() % 8 + 1;
			while(1) {
				if(!b2.makeMove(move)) {
					continue;
				}
				else
					break;
			}

			if(b2.checkWin()) {
				cout << "o wins!" << endl;
				done = true;
				break;
			}
			
			b1.show();
			
		}
	}	
	cout << "Done!" << endl;
	
	return 0;
}


EDIT:fixed a large bug

EDIT2: I realize that it sometimes lags becuase the random moves keep getting rejected. This problem will disappear once I have written a good AI
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!

Last edited by Jessehk; Dec 9th, 2005 at 10:07 PM.
Jessehk is offline   Reply With Quote
 

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump