Commits

Guy B  committed 71a1e9d

initial commit

  • Participants

Comments (0)

Files changed (5)

+*
+!.gitignore
+!*.c
+!*.h
+!*.sh
+!Makefile
+!README
+# tictactoe - a basic tic tac toe game
+# author - Guy Bianco: gjbianco
+
+SRC = tictactoe.c
+OBJ = ${SRC:.c=.o}
+
+all: options tictactoe
+
+options:
+	@echo tictactoe build options:
+	@echo "CFLAGS  = ${CFLAGS}"
+	@echo "LDFLAGS = ${LDFLAGS}"
+	@echo "CC      = ${CC}"
+
+tictactoe:
+	@echo CC -o $@
+	@${CC} -o $@ ${SRC} -std=c99
+Just a little tic tac toe game I've put together. Nothing complicated (right now).
+
+I plan to use this as a sort of testbed for game development ideas and learning. For example, I'll probably end up making various GUIs for it in order to learn different graphics/windows libraries (e.g. gtk, ncurses, SDL, OpenGL, etc.).
+
+Function-wise, I believe it is mostly complete. The version in [master] should work without any major bugs.
+
+Current features (in [master]):
+- move checking: checks to see if the attempted move has already been used (does not check bounds, currently).
+- draws the updated board after every move
+- determines which player won (without having to finish the board); also includes a "cat game" (very basic implementation; in other words, if all 9 spaces are filled and there was no winner)
+
+I plan on updating the current input system that's in the [master] version. The current one is neither intuitive nor efficient (I want to have at least one of those, if not both).
+
+BUGS
+- entering anything other than a number seems to end the game with no winner (cat game)
+- can enter coordinates outside bounds (e.g. 8)
+- not necessarily a bug, but a very nonintuitive and inefficient move input system
+- no smart determination of cat game; i.e. all 9 spaces have to be filled without a winner (even if there was already no way for anyone to win). for example, if O makes the move at (3,3) and the board looks like the following:
+	+-----------+
+	| X | O | X |
+	+---+---+---+
+	| O | O | X |
+	+---+---+---+
+	|   | X | O |
+	+-----------+
+
+there is no possible way for anybody to win, but the game requires the last move for the game to actually finish.
+#!/bin/bash
+gcc -o tictactoe -std=c99 -Wall tictactoe.c -g
+#include <stdio.h>
+
+//returns array index for the given position
+char get_position(char posx, char posy) {
+	return posx+(3*posy);
+}
+
+//get the value stored at location at posx, posy on the given board
+char get_location_value(char* board, char posx, char posy) {
+	return board[get_position(posx, posy)];
+}
+
+//places an X on the board at posx, posy
+void x_move(char* board, char posx, char posy) {
+	board[get_position(posx, posy)] = 1;
+}
+
+//places an O on the board at posx, posy
+void o_move(char* board, char posx, char posy) {
+	board[get_position(posx, posy)] = 2;
+}
+
+//asks the player for their move
+void player_move(int* loc) {
+	printf("enter x position: ");
+
+	scanf("%d", loc);
+	loc[0]--;
+
+	printf("enter y position: ");
+
+	scanf("%d", loc+1);
+	loc[1]--;
+
+	printf("\n");
+}
+
+//prints out welcome message
+void print_welcome() {
+	printf("use the following grid coordinates to enter in your moves.\n");
+	printf("   | 1 | 2 | 3 | <--Y coordinate\n");
+	printf("-- +-----------+\n");
+	printf("1  |11 |12 |13 |\n");
+	printf("-- +---|---|---|\n");
+	printf("2  |21 |22 |23 |\n");
+	printf("-- +---|---|---|\n");
+	printf("3  |31 |32 |33 |\n");
+	printf("-- +-----------+\n");
+	printf("^ X coordinate\n\n");
+}
+
+//checks to see if any win conditions are met
+//	0 - no winner (yet)
+//	1 - X wins
+//	2 - O wins
+char check_win(char* board) {
+	//check horizontal
+	for(int i = 0; i < 9; i+=3)
+		if(board[i] != 0 && board[i] == board[i+1] && board[i+1] == board[i+2])
+			return board[i];
+
+	//check vertical
+	for(int i = 0; i < 3; i++)
+		if(board[i] != 0 && board[i] == board[i+3] && board[i+3] == board[i+6])
+			return board[i];
+
+	//check diagonals
+	if(board[0] != 0 && board[0] == board[4] && board[4] == board[8])
+		return board[0];
+	if(board[2] != 0 && board[2] == board[4] && board[4] == board[7])
+		return board[0];
+
+	//no winner (yet)
+	return 0;
+}
+
+//prints ("renders") the current board to the screen
+void render_board(char* board) {
+	//do some sort of "clear section"?
+
+	printf("+-----------+\n");
+	for(char i = 0; i < 3; i++) {
+		printf("| ");
+		for(int j = 0; j < 3; j++) {
+			switch(board[i+3*j]) {
+				case 0:
+					printf(" ");
+					break;
+				case 1:
+					printf("X");
+					break;
+				case 2:
+					printf("O");
+					break;
+			}
+
+			printf(" | ");
+		}
+		printf("\n");
+		if(i < 2)
+			printf("+---+---+---+\n");
+	}
+	printf("+-----------+\n\n");
+}
+
+int main() {
+	//0 - no move here
+	//1 - x here
+	//2 - o here
+	char board[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+	//0 - x's move
+	//1 - o's move
+	char curr_move = 0;
+
+	//player's current location choice
+	int loc[2] = {0, 0};
+
+	//print the welcome message for the game
+	print_welcome();
+
+	//main game loop
+	for(int i = 0; i < 9; i++) {
+		//set player's move validity to false
+		char valid = 0;
+
+		//tell the player whose turn it currently is
+		printf("It's %c's turn!\n", curr_move ? 'O' : 'X');
+
+		//asks the player for a move until they enter a valid (nonused) location
+		while(!valid) {
+			valid = 1;
+
+			player_move(loc);
+
+			if(valid && board[get_position(loc[0], loc[1])] != 0) {
+				printf("place already taken!\n");
+				valid = 0;
+			}
+		}
+
+		//places the appropriate value at the location specified by the player
+		if(!curr_move) {
+			//currently X's turn
+			x_move(board, loc[0], loc[1]);
+			curr_move++;
+		} else {
+			//currently O's turn
+			o_move(board, loc[0], loc[1]);
+			curr_move--;
+		}
+
+		//updates the board for the player
+		render_board(board);
+
+		//checks if any win conditions have been met
+		char win = check_win(board);
+		if(win) {
+			printf("%c wins!\n", win == 1 ? 'X' : 'O');
+			return 0;
+		}
+	}
+
+	//cat game
+	printf("cat game! no winner\n");
+
+	return 0;
+}