diff --git a/README.md b/README.md index 082e4ed..6a94e9a 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,7 @@ All directions are here... https://github.com/accesscode-2-2/unit-0/tree/master/project Instructions on forking and pull requests here... https://github.com/accesscode-2-2/how-to-pr + +hi my name is eric + +lololololol \ No newline at end of file diff --git a/TicTacToe/TicTacToe.xcodeproj/project.pbxproj b/TicTacToe/TicTacToe.xcodeproj/project.pbxproj index 71ad89c..d7e93bd 100644 --- a/TicTacToe/TicTacToe.xcodeproj/project.pbxproj +++ b/TicTacToe/TicTacToe.xcodeproj/project.pbxproj @@ -7,6 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + 692E08551B533C8300A52FCC /* NSString+isNumeric.m in Sources */ = {isa = PBXBuildFile; fileRef = 692E08541B533C8300A52FCC /* NSString+isNumeric.m */; }; + 695078051B4C867600735A8D /* Game.m in Sources */ = {isa = PBXBuildFile; fileRef = 695078041B4C867600735A8D /* Game.m */; }; + 695078081B4C880600735A8D /* NSArray+LineChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 695078071B4C880600735A8D /* NSArray+LineChecker.m */; }; + 6950780B1B4C893600735A8D /* MyTicTacToeGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 6950780A1B4C893600735A8D /* MyTicTacToeGame.m */; }; + 6950780E1B4C97FD00735A8D /* Player.m in Sources */ = {isa = PBXBuildFile; fileRef = 6950780D1B4C97FD00735A8D /* Player.m */; }; + 6965035B1B51B1CD00300B68 /* ComputerPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6965035A1B51B1CD00300B68 /* ComputerPlayer.m */; }; + 698005621B547295008F3E8A /* TicTacToeRowGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 698005611B547295008F3E8A /* TicTacToeRowGenerator.m */; }; 8D9789E41B3C9A70007CF4CF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D9789E31B3C9A70007CF4CF /* main.m */; }; /* End PBXBuildFile section */ @@ -23,6 +30,20 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 692E08531B533C8300A52FCC /* NSString+isNumeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+isNumeric.h"; sourceTree = ""; }; + 692E08541B533C8300A52FCC /* NSString+isNumeric.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+isNumeric.m"; sourceTree = ""; }; + 695078031B4C867600735A8D /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = ""; }; + 695078041B4C867600735A8D /* Game.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Game.m; sourceTree = ""; }; + 695078061B4C880600735A8D /* NSArray+LineChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+LineChecker.h"; sourceTree = ""; }; + 695078071B4C880600735A8D /* NSArray+LineChecker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+LineChecker.m"; sourceTree = ""; }; + 695078091B4C893600735A8D /* MyTicTacToeGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTicTacToeGame.h; sourceTree = ""; }; + 6950780A1B4C893600735A8D /* MyTicTacToeGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTicTacToeGame.m; sourceTree = ""; }; + 6950780C1B4C97FD00735A8D /* Player.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Player.h; sourceTree = ""; }; + 6950780D1B4C97FD00735A8D /* Player.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Player.m; sourceTree = ""; }; + 696503591B51B1CD00300B68 /* ComputerPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComputerPlayer.h; sourceTree = ""; }; + 6965035A1B51B1CD00300B68 /* ComputerPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ComputerPlayer.m; sourceTree = ""; }; + 698005601B547295008F3E8A /* TicTacToeRowGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TicTacToeRowGenerator.h; sourceTree = ""; }; + 698005611B547295008F3E8A /* TicTacToeRowGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TicTacToeRowGenerator.m; sourceTree = ""; }; 8D9789E01B3C9A70007CF4CF /* TicTacToe */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TicTacToe; sourceTree = BUILT_PRODUCTS_DIR; }; 8D9789E31B3C9A70007CF4CF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -58,6 +79,20 @@ isa = PBXGroup; children = ( 8D9789E31B3C9A70007CF4CF /* main.m */, + 6950780C1B4C97FD00735A8D /* Player.h */, + 6950780D1B4C97FD00735A8D /* Player.m */, + 695078031B4C867600735A8D /* Game.h */, + 695078041B4C867600735A8D /* Game.m */, + 696503591B51B1CD00300B68 /* ComputerPlayer.h */, + 6965035A1B51B1CD00300B68 /* ComputerPlayer.m */, + 695078091B4C893600735A8D /* MyTicTacToeGame.h */, + 6950780A1B4C893600735A8D /* MyTicTacToeGame.m */, + 698005601B547295008F3E8A /* TicTacToeRowGenerator.h */, + 698005611B547295008F3E8A /* TicTacToeRowGenerator.m */, + 695078061B4C880600735A8D /* NSArray+LineChecker.h */, + 695078071B4C880600735A8D /* NSArray+LineChecker.m */, + 692E08531B533C8300A52FCC /* NSString+isNumeric.h */, + 692E08541B533C8300A52FCC /* NSString+isNumeric.m */, ); path = TicTacToe; sourceTree = ""; @@ -118,7 +153,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6950780B1B4C893600735A8D /* MyTicTacToeGame.m in Sources */, + 698005621B547295008F3E8A /* TicTacToeRowGenerator.m in Sources */, + 692E08551B533C8300A52FCC /* NSString+isNumeric.m in Sources */, 8D9789E41B3C9A70007CF4CF /* main.m in Sources */, + 695078081B4C880600735A8D /* NSArray+LineChecker.m in Sources */, + 6965035B1B51B1CD00300B68 /* ComputerPlayer.m in Sources */, + 695078051B4C867600735A8D /* Game.m in Sources */, + 6950780E1B4C97FD00735A8D /* Player.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -235,6 +277,7 @@ 8D9789E91B3C9A70007CF4CF /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/TicTacToe/TicTacToe/ComputerPlayer.h b/TicTacToe/TicTacToe/ComputerPlayer.h new file mode 100644 index 0000000..b9ecca1 --- /dev/null +++ b/TicTacToe/TicTacToe/ComputerPlayer.h @@ -0,0 +1,13 @@ +// +// ComputerPlayer.h +// TicTacToe +// +// Created by Z on 7/11/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +@interface ComputerPlayer : NSObject + +@end diff --git a/TicTacToe/TicTacToe/ComputerPlayer.m b/TicTacToe/TicTacToe/ComputerPlayer.m new file mode 100644 index 0000000..c126da7 --- /dev/null +++ b/TicTacToe/TicTacToe/ComputerPlayer.m @@ -0,0 +1,92 @@ +// +// ComputerPlayer.m +// TicTacToe +// +// Created by Z on 7/11/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "ComputerPlayer.h" + +@implementation ComputerPlayer + + +// //Easy Mode computer move +// if (_difficulty == 1) { +// int computerMove = arc4random_uniform(_maxIndex + 1); +// if ((![[_gameboard objectAtIndex:computerMove] isEqual: @"~X"]) && (![[_gameboard objectAtIndex:computerMove] isEqual: @"~O"])) { +// NSLog(@"Computer is making a move..."); +// sleep(1.5); +// [_gameboard replaceObjectAtIndex:(NSUInteger)computerMove withObject:@"~O"]; + + + +//-(BOOL)checkWin{ +// +// NSString *playerPiece; +// +// for (int i = 0; i < 2; i++) { +// +// //sets player piece for each of the two loops +// if (i == 1) { +// playerPiece = @"~X"; +// _winner = @"Player 1"; +// } +// else{ +// playerPiece = @"~O"; +// _winner = @"Player 2"; +// } +// +// // |X|X|X| +// // | | | | +// // | | | | +// if (([_gameboard[0] isEqual:playerPiece]) && ([_gameboard[1] isEqual:playerPiece]) && ([_gameboard[2] isEqual:playerPiece])){ +// return YES; +// } +// // | | | | +// // |X|X|X| +// // | | | | +// if (([_gameboard[3] isEqual:playerPiece]) && ([_gameboard[4] isEqual:playerPiece]) && ([_gameboard[5] isEqual:playerPiece])){ +// return YES; +// } +// // | | | | +// // | | | | +// // |X|X|X| +// if (([_gameboard[6] isEqual:playerPiece]) && ([_gameboard[7] isEqual:playerPiece]) && ([_gameboard[8] isEqual:playerPiece])){ +// return YES; +// } +// // |X| | | +// // |X| | | +// // |X| | | +// if (([_gameboard[0] isEqual:playerPiece]) && ([_gameboard[3] isEqual:playerPiece]) && ([_gameboard[6] isEqual:playerPiece])){ +// return YES; +// } +// // | |X| | +// // | |X| | +// // | |X| | +// if (([_gameboard[1] isEqual:playerPiece]) && ([_gameboard[4] isEqual:playerPiece]) && ([_gameboard[7] isEqual:playerPiece])){ +// return YES; +// } +// // | | |X| +// // | | |X| +// // | | |X| +// if (([_gameboard[2] isEqual:playerPiece]) && ([_gameboard[5] isEqual:playerPiece]) && ([_gameboard[8] isEqual:playerPiece])){ +// return YES; +// } +// // |X| | | +// // | |X| | +// // | | |X| +// if (([_gameboard[0] isEqual:playerPiece]) && ([_gameboard[4] isEqual:playerPiece]) && ([_gameboard[8] isEqual:playerPiece])){ +// return YES; +// } +// // | | |X| +// // | |X| | +// // |X| | | +// if (([_gameboard[2] isEqual:playerPiece]) && ([_gameboard[4] isEqual:playerPiece]) && ([_gameboard[6] isEqual:playerPiece])){ +// return YES; +// } +// +// } +// return NO; +//} +@end diff --git a/TicTacToe/TicTacToe/Game.h b/TicTacToe/TicTacToe/Game.h new file mode 100644 index 0000000..95aa6dd --- /dev/null +++ b/TicTacToe/TicTacToe/Game.h @@ -0,0 +1,62 @@ +// +// Game.h +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +typedef NS_ENUM(NSUInteger, PossibleWinner) { + PlayerX, + PlayerO, + ComputerX, + ComputerO, + noWinNextMove +}; + +typedef NS_ENUM(NSUInteger, Difficulty) { + Easy = 1, + Medium = 2, + Hard =3 +}; + +typedef NS_ENUM(NSUInteger, Mode) { + PlayerVsPlayer = 1, + PlayerVsComputer = 2, + ComputerVsComputer =3 +}; + +@interface Game : NSObject + +-(BOOL)checkWin; +-(BOOL)getWin; + +-(BOOL)checkDraw; + +-(void)setupGame; + +- (NSMutableArray *)getGameBoard; + +-(void)printBoard; +-(void)printTutorialBoard; + +-(void)turn; +-(int)getTurnCount; + +-(void)setGameSize:(int)size; +-(int)getGameSize; + +- (void)getGameBoard:(NSArray *)gameBoard; + +//Easy, Medium, Hard +-(void)setDifficulty:(int)level; +-(int)getDifficulty; + +//Player vs. Player OR Player vs. Computer +-(void)setMode:(int)mode; +-(int)getMode; + + +@end diff --git a/TicTacToe/TicTacToe/Game.m b/TicTacToe/TicTacToe/Game.m new file mode 100644 index 0000000..30e8d75 --- /dev/null +++ b/TicTacToe/TicTacToe/Game.m @@ -0,0 +1,338 @@ +// +// Game.m +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "Game.h" +#import "Player.h" +#import "NSArray+LineChecker.h" +#import "NSString+isNumeric.h" +#import "TicTacToeRowGenerator.h" + +NSString * const PossibleWinnerString = @"PossibleWinnerString"; + +@implementation Game { + int _mode; + + int _difficulty; + + int _playerTurn; + int _turnCount; + + BOOL _win; + NSString *_winner; + + NSMutableArray *_gameboard; + int _gameSize; + int _maxIndex; + + int _currentMove; +} + +- (NSMutableArray *)getGameBoard { + return _gameboard; +} + +-(void)setDifficulty:(int)level{ + _difficulty = level; +} + +-(int)getDifficulty{ + return _difficulty; +} + +-(void)setGameSize:(int)size{ + _gameSize = size; +} + +-(int)getGameSize{ + return _gameSize; +} + +-(void)setMode:(int)mode{ + _mode = mode; +} +-(int)getMode{ + return _mode; +} + +-(BOOL)getWin{ + return _win; +} + +-(int)getTurnCount{ + return _turnCount; +} + +-(void)setupGame { + + //greeting + NSLog(@"Welcome to Derek's and Eric's TicTacToe!"); + _win = NO; + _playerTurn = 1; + + //calculate max index + _maxIndex = (pow(_gameSize, 2) - 1); + + //fill gameboard with the indices of the positions to occupy + _gameboard = [[NSMutableArray alloc] init]; + for (int i = 0; i < pow (_gameSize,2); i++) { + + // create a string from i + NSString *placeNumber = [NSString stringWithFormat:@"%d",i]; + int lengthOfPlaceNumber = (int)[placeNumber length]; + + // if the string is of a single digit number, padd with 0 for formatting purposes + if (lengthOfPlaceNumber == 1) { + NSString *zero = [NSString stringWithFormat:@"0"]; + placeNumber = [zero stringByAppendingString:placeNumber]; + } + [_gameboard addObject: placeNumber]; + } +} + +-(NSString *)getPlayerPiece{ + NSString *playerPiece; + if (_playerTurn == 2) { + playerPiece = @"~O"; + } + else{ + playerPiece = @"~X"; + } + return playerPiece; +} + +-(void)turn{ + BOOL moveMade = NO; + while (moveMade == NO) { + + NSString *stringOfCurrentMove; + + if (_mode == 1) { //Player vs. Player + stringOfCurrentMove = [self makeMove]; + } + else if (_mode == 2){ //Player vs. Computer + if (_playerTurn == 1) { + stringOfCurrentMove = [self makeMove]; + } + else{ + stringOfCurrentMove = [self computerMakeMove]; + } + } + + if (([_gameboard[_currentMove] isEqual: stringOfCurrentMove]) && (_currentMove<=_maxIndex) && (_currentMove>=0)) { + [_gameboard replaceObjectAtIndex:(NSUInteger)_currentMove withObject:[self getPlayerPiece]]; + moveMade = YES; + + if ((_mode != 1) && (_playerTurn == 2)) { + NSLog(@"Computer is thinking..."); + usleep(1e6); + NSLog(@"Computer has made a move!"); + } + + } + else { + if (_mode == 1) { + NSLog(@"Invalid move. Enter a number from 0-%d.",_maxIndex); + } + } + } + _turnCount = _turnCount + 1; + + if (_turnCount % 2 != 0) { + _playerTurn = 2; + } + else{ + _playerTurn = 1; + } +} + +-(NSString *)makeMove{ + NSLog(@"Player %d make your move:",_playerTurn); + scanf("%d",&_currentMove); + fpurge(stdin); + + NSString *stringOfCurrentMove = [NSString stringWithFormat:@"%02d",_currentMove]; + + return stringOfCurrentMove; +} + +-(NSString *)computerMakeMove{ + + NSString *stringOfCurrentMove = [[NSString alloc] init]; + + if (_difficulty == Easy) { + _currentMove = arc4random_uniform(_maxIndex + 1); + stringOfCurrentMove = [NSString stringWithFormat:@"%02d",_currentMove]; + return stringOfCurrentMove; + } + + else if (_difficulty == Medium){ + + stringOfCurrentMove = [NSString stringWithString:[self makeWinMove]]; + + if ([stringOfCurrentMove isEqualToString:@"none"]) { //if no win move to make + + stringOfCurrentMove = [self makeBlockMove]; + } + + if ([stringOfCurrentMove isEqualToString:@"none"]) { //if no block move to make + + _currentMove = arc4random_uniform(_maxIndex + 1); + stringOfCurrentMove = [NSString stringWithFormat:@"%02d",_currentMove]; //random move + } + + _currentMove = [stringOfCurrentMove intValue]; + return stringOfCurrentMove; + } + + else if (_difficulty == Hard){ + + } + + +return @"HEHEE"; +} + +//-(NSString *)makePowerMove{ //checks board and outputs available move of highest power +// NSDictionary * const movePowers = @{ +// @"00" : @300, +// @"01" : @200, +// @"02" : @300, +// @"03" : @200, +// @"04" : @400, +// @"05" : @200, +// @"06" : @300, +// @"07" : @200, +// @"08" : @300, +// }; +// +// NSString *powerMove = [[NSString alloc] init]; +// for (int i = 0; [_gameboard count]; i++) { +// <#statements#> +// } +// +//} + + + +-(NSString *)makeBlockMove{ + + NSDictionary *possibleWinnerAndWinningMove = [self whoCanWinOnNextMove]; + + if ([[possibleWinnerAndWinningMove objectForKey:@"PossibleWinner"] isEqualToString:@"PlayerX"] ) { + return [possibleWinnerAndWinningMove objectForKey:@"WinningMove"]; + } + return @"none"; +} + +-(NSString *)makeWinMove{ + + NSDictionary *possibleWinnerAndWinningMove = [self whoCanWinOnNextMove]; + + if ([[possibleWinnerAndWinningMove objectForKey:@"PossibleWinner"] isEqualToString:@"PlayerO"] ) { + return [possibleWinnerAndWinningMove objectForKey:@"WinningMove"]; + } + return @"none"; +} + +-(NSDictionary *) whoCanWinOnNextMove { + + NSArray *allLines = [self makeAllLines]; + + for (int i = 0; i< allLines.count; i++) { + + for (int j = 0; j < [[allLines objectAtIndex:i] count]; j++){ + + NSDictionary *countsForElementsInLine = [self lineInspect:[[allLines objectAtIndex:i] objectAtIndex:j]]; + + if (([[countsForElementsInLine valueForKey:@"xPieceCount"] intValue] == _gameSize - 1) && ([[countsForElementsInLine valueForKey: @"IndicesOfSpaces"] count] == 1)) { + NSDictionary *possibleWinnerAndWinningMove = [NSDictionary dictionaryWithObjectsAndKeys:[[countsForElementsInLine valueForKey: @"IndicesOfSpaces"]objectAtIndex:0] , @"WinningMove", @"PlayerX", @"PossibleWinner", nil]; + return possibleWinnerAndWinningMove; //returns PlayerX and WinningMove + } + else if (([[countsForElementsInLine valueForKey:@"oPieceCount"] intValue] == _gameSize - 1) && ([[countsForElementsInLine valueForKey: @"IndicesOfSpaces"] count] == 1)) { + NSDictionary *possibleWinnerAndWinningMove = [NSDictionary dictionaryWithObjectsAndKeys:[[countsForElementsInLine valueForKey: @"IndicesOfSpaces"] objectAtIndex:0] , @"WinningMove", @"PlayerO", @"PossibleWinner", nil]; //returns PlayerO and WinningMove + return possibleWinnerAndWinningMove; + + } + } + } + + NSDictionary *noWinner = @{ + @"WinningMove" : @"none", + @"PossibleWinner":@"none" + }; + + return noWinner; +} + +-(NSArray *)makeAllLines{ + NSArray *horizontals = [TicTacToeRowGenerator allLinesForDirection:Horizonal withGame:_gameboard]; + NSArray *verticals = [TicTacToeRowGenerator allLinesForDirection:Vertical withGame:_gameboard]; + NSArray *diagonals = [TicTacToeRowGenerator allLinesForDirection:Diagonal withGame:_gameboard]; + NSArray *allLines = [NSArray arrayWithObjects:horizontals,verticals,diagonals, nil]; + + return allLines; +} + +-(NSDictionary *)lineInspect:(NSMutableArray*)line{ + NSNumber *xPieceCount = [NSNumber numberWithInt:0]; + NSNumber *oPieceCount = [NSNumber numberWithInt:0]; + NSNumber *spaceCount = [NSNumber numberWithInt:0]; + NSMutableArray *IndicesOfSpaces = [[NSMutableArray alloc] init]; + + for (int j = 0; j < [line count]; j++) { + if ([[line objectAtIndex:j] isEqual: @"~X"]) { + xPieceCount = [NSNumber numberWithInt: [xPieceCount intValue] + 1 ]; + } + else if ([[line objectAtIndex:j] isEqual: @"~O"]) { + oPieceCount = [NSNumber numberWithInt: [oPieceCount intValue] + 1 ]; + } + else { + [IndicesOfSpaces addObject:[line objectAtIndex:j]]; + spaceCount = [NSNumber numberWithInt: [spaceCount intValue] + 1 ]; + } + } + + NSArray *keyArray = [NSArray arrayWithObjects: @"xPieceCount", @"oPieceCount", @"spaceCount", @"IndicesOfSpaces",nil]; + NSArray *valArray = [NSArray arrayWithObjects: xPieceCount, oPieceCount, spaceCount, IndicesOfSpaces, nil]; + + NSDictionary *countsForElementsInLine = [NSDictionary dictionaryWithObjects:valArray forKeys:keyArray]; + return countsForElementsInLine; +} + +-(BOOL)checkWin{ + + NSArray *allLines = [self makeAllLines]; + + for (int i = 0; i< allLines.count; i++) { + + for (int j = 0; j < [[allLines objectAtIndex:i] count]; j++){ + + NSDictionary *countsForElementsInLine = [self lineInspect:[[allLines objectAtIndex:i] objectAtIndex:j]]; + + if ([[countsForElementsInLine valueForKey:@"xPieceCount"] intValue] == _gameSize) { + _win = TRUE; + return TRUE; + } + else if ([[countsForElementsInLine valueForKey:@"oPieceCount"] intValue] == _gameSize) { + _win = TRUE; + return TRUE; + } + } + } + return FALSE; +} + +-(BOOL)checkDraw{ + if ((_win == NO) && (_turnCount == (_maxIndex + 1))){ + return TRUE; + } + return FALSE; +} + + +@end diff --git a/TicTacToe/TicTacToe/MyTicTacToeGame.h b/TicTacToe/TicTacToe/MyTicTacToeGame.h new file mode 100644 index 0000000..c7efb06 --- /dev/null +++ b/TicTacToe/TicTacToe/MyTicTacToeGame.h @@ -0,0 +1,18 @@ +// +// MyTicTacToeGame.h +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +@class Game; + +@interface MyTicTacToeGame: NSObject + ++ (void)printBoard:(Game *)game; ++ (void)printTutorialBoard:(Game *)game; + +@end diff --git a/TicTacToe/TicTacToe/MyTicTacToeGame.m b/TicTacToe/TicTacToe/MyTicTacToeGame.m new file mode 100644 index 0000000..211aee8 --- /dev/null +++ b/TicTacToe/TicTacToe/MyTicTacToeGame.m @@ -0,0 +1,55 @@ +// +// MyTicTacToeGame.m +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "MyTicTacToeGame.h" +#import "Game.h" + +@implementation MyTicTacToeGame + ++ (void)printBoard:(Game *)game { //class method + for (int i = 0; i < pow ([game getGameSize],2); i++) { + + NSString *placeHolderString = [[game getGameBoard] objectAtIndex:i]; + const char *placeHolderCharString = [placeHolderString cStringUsingEncoding:NSUTF8StringEncoding]; + + if ((i >= [game getGameSize]) && (i % [game getGameSize] == 0)) { + printf("\n|%s|", placeHolderCharString); + } + else{ + printf("|%s|", placeHolderCharString); + } + } + printf("\n"); +} + ++ (void)printTutorialBoard:(Game *)game{ //class method + for (int i = 0; i < pow ([game getGameSize],2); i++) { + + // create a string from i + NSString *placeNumber = [NSString stringWithFormat:@"%d",i]; + int lengthOfPlaceNumber = (int)[placeNumber length]; + + // check the length of the sting + if (lengthOfPlaceNumber == 1) { + NSString *zero = [NSString stringWithFormat:@"0"]; + placeNumber = [zero stringByAppendingString:placeNumber]; + } + //convert NSString to char string + const char *placeNumberCharString = [placeNumber cStringUsingEncoding: NSUTF8StringEncoding]; + + if ((i >= [game getGameSize]) && (i % [game getGameSize] == 0)) { + printf("\n|%s|", placeNumberCharString); + } + else{ + printf("|%s|", placeNumberCharString); + } + } + printf("\n"); +} + +@end diff --git a/TicTacToe/TicTacToe/NSArray+LineChecker.h b/TicTacToe/TicTacToe/NSArray+LineChecker.h new file mode 100644 index 0000000..63d45e3 --- /dev/null +++ b/TicTacToe/TicTacToe/NSArray+LineChecker.h @@ -0,0 +1,15 @@ +// +// NSArray+LineChecker.h +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +@interface NSArray (LineChecker) + +-(BOOL) areAllObjectsAreIdentical; + +@end diff --git a/TicTacToe/TicTacToe/NSArray+LineChecker.m b/TicTacToe/TicTacToe/NSArray+LineChecker.m new file mode 100644 index 0000000..083ed3f --- /dev/null +++ b/TicTacToe/TicTacToe/NSArray+LineChecker.m @@ -0,0 +1,18 @@ +// +// NSArray+LineChecker.m +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "NSArray+LineChecker.h" + +@implementation NSArray (LineChecker) + +-(BOOL) areAllObjectsAreIdentical{ //category method for NSArray + NSSet *set = [NSSet setWithArray:self]; + return ([set count] <= 1); +} + +@end diff --git a/TicTacToe/TicTacToe/NSString+isNumeric.h b/TicTacToe/TicTacToe/NSString+isNumeric.h new file mode 100644 index 0000000..9bc3f76 --- /dev/null +++ b/TicTacToe/TicTacToe/NSString+isNumeric.h @@ -0,0 +1,14 @@ +// +// NSString+isNumeric.h +// TicTacToe +// +// Created by Z on 7/12/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +@interface NSString (isNumeric) +- (BOOL) isAllDigits; +- (BOOL) isNumeric; +@end diff --git a/TicTacToe/TicTacToe/NSString+isNumeric.m b/TicTacToe/TicTacToe/NSString+isNumeric.m new file mode 100644 index 0000000..a4f1753 --- /dev/null +++ b/TicTacToe/TicTacToe/NSString+isNumeric.m @@ -0,0 +1,33 @@ +// +// NSString+isNumeric.m +// TicTacToe +// +// Created by Z on 7/12/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "NSString+isNumeric.h" + +@implementation NSString (isNumeric) + +- (BOOL) isAllDigits{ + NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + NSRange r = [self rangeOfCharacterFromSet: nonNumbers]; + return r.location == NSNotFound; +} + +-(BOOL) isNumeric{ + NSScanner *sc = [NSScanner scannerWithString: self]; + // We can pass NULL because we don't actually need the value to test + // for if the string is numeric. This is allowable. + if ( [sc scanFloat:NULL] ) + { + // Ensure nothing left in scanner so that "42foo" is not accepted. + // ("42" would be consumed by scanFloat above leaving "foo".) + return [sc isAtEnd]; + } + // Couldn't even scan a float :( + return NO; +} + +@end diff --git a/TicTacToe/TicTacToe/Player.h b/TicTacToe/TicTacToe/Player.h new file mode 100644 index 0000000..0eb5747 --- /dev/null +++ b/TicTacToe/TicTacToe/Player.h @@ -0,0 +1,13 @@ +// +// Player.h +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +@interface Player : NSObject +//seperate humman and computer +@end diff --git a/TicTacToe/TicTacToe/Player.m b/TicTacToe/TicTacToe/Player.m new file mode 100644 index 0000000..73a288e --- /dev/null +++ b/TicTacToe/TicTacToe/Player.m @@ -0,0 +1,13 @@ +// +// Player.m +// TicTacToe +// +// Created by Z on 7/7/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "Player.h" + +@implementation Player + +@end diff --git a/TicTacToe/TicTacToe/TicTacToeRowGenerator.h b/TicTacToe/TicTacToe/TicTacToeRowGenerator.h new file mode 100644 index 0000000..cbc9dba --- /dev/null +++ b/TicTacToe/TicTacToe/TicTacToeRowGenerator.h @@ -0,0 +1,22 @@ +// +// TicTacToeRowGenerator.h +// TicTacToe +// +// Created by Z on 7/13/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import + +typedef NS_ENUM(NSUInteger, Direction) { + Horizonal, + Vertical, + Diagonal +}; + +@interface TicTacToeRowGenerator : NSObject + ++ (NSMutableArray *)allLinesForDirection:(Direction)direction + withGame:(NSArray *)gameBoard; + +@end diff --git a/TicTacToe/TicTacToe/TicTacToeRowGenerator.m b/TicTacToe/TicTacToe/TicTacToeRowGenerator.m new file mode 100644 index 0000000..a28dbc0 --- /dev/null +++ b/TicTacToe/TicTacToe/TicTacToeRowGenerator.m @@ -0,0 +1,110 @@ +// +// TicTacToeRowGenerator.m +// TicTacToe +// +// Created by Z on 7/13/15. +// Copyright (c) 2015 Mike Kavouras. All rights reserved. +// + +#import "TicTacToeRowGenerator.h" +#import "NSString+isNumeric.h" + +@implementation TicTacToeRowGenerator + ++ (NSMutableArray *)allLinesForDirection:(Direction)direction + withGame:(NSArray *)gameBoard { + + // check if valid gameboard + // check if valid direction + + switch (direction) { + case Horizonal: + return [self horizontalLinesForGame:gameBoard]; + case Vertical: + return [self verticalLinesForGame:gameBoard]; + case Diagonal: + return [self diagonalLinesForGame:gameBoard]; + } +} + ++ (NSMutableArray *)horizontalLinesForGame:(NSArray *)gameBoard { + + NSInteger sizeOfGame = sqrt(gameBoard.count); + NSMutableArray *lines = [[NSMutableArray alloc] init]; + + // this sucks it's state + NSMutableArray *line = [[NSMutableArray alloc] init]; + + for (int i = 0; i < gameBoard.count; i++) { + + NSString *currentVal = [gameBoard objectAtIndex:i]; + [line addObject:currentVal]; + + if ([line count] == sizeOfGame) { //line array reaches the gameSize + [lines addObject:[NSArray arrayWithArray:line]]; + [line removeAllObjects]; + } + } + + return lines; +} + ++ (NSMutableArray *)verticalLinesForGame:(NSArray *)gameBoard { + + NSInteger sizeOfGame = sqrt(gameBoard.count); + NSMutableArray *lines = [[NSMutableArray alloc] init]; + + NSInteger currentIndex; + NSInteger lastIndex; + + for (int i = 0; i < sizeOfGame; i++) { + currentIndex = i; + lastIndex = 0; + + NSMutableArray *line = [[NSMutableArray alloc] init]; + for (int i = 0; i < sizeOfGame; i++) { + [line addObject:[gameBoard objectAtIndex:currentIndex]]; + lastIndex = currentIndex; + currentIndex = lastIndex + sizeOfGame; + } + + [lines addObject:line]; + } + + return lines; +} + ++ (NSMutableArray *)diagonalLinesForGame:(NSArray *)gameBoard { + + NSInteger sizeOfGame = sqrt(gameBoard.count); + NSMutableArray *lines = [[NSMutableArray alloc] init]; + + NSInteger currentIndex = 0; + NSInteger lastIndex = 0; + + NSMutableArray *lineLR = [[NSMutableArray alloc] init]; + for (int i = 0; i < sizeOfGame; i++) { + [lineLR addObject:[gameBoard objectAtIndex:currentIndex]]; + lastIndex = currentIndex; + currentIndex = lastIndex + sizeOfGame + 1; + } + + [lines addObject:lineLR]; + + currentIndex = sizeOfGame - 1; + lastIndex = sizeOfGame - 1; + + NSMutableArray *lineRL = [[NSMutableArray alloc] init]; + for (int i = 0; i < sizeOfGame; i++) { + [lineRL addObject:[gameBoard objectAtIndex:currentIndex]]; + lastIndex = currentIndex; + currentIndex = lastIndex + sizeOfGame - 1; + } + + [lines addObject:lineRL]; + + return lines; +} + + +@end diff --git a/TicTacToe/TicTacToe/main.m b/TicTacToe/TicTacToe/main.m index 3a713ee..b8212d0 100644 --- a/TicTacToe/TicTacToe/main.m +++ b/TicTacToe/TicTacToe/main.m @@ -7,11 +7,115 @@ // #import +#import "MyTicTacToeGame.h" +#import "TicTacToeRowGenerator.h" +#import "Game.h" + int main(int argc, const char * argv[]) { @autoreleasepool { - // insert code here... - NSLog(@"Hello, World!"); + + Game *ticTacToe =[[Game alloc]init]; + + //set game mode + BOOL modeSet = NO; + while (modeSet == NO) { + NSLog(@"Select Game Mode:"); + NSLog(@" 1) Player vs. Player"); + NSLog(@" 2) Player vs. Computer"); + NSLog(@" 3) Computer vs. Computer"); + int userGameMode; + scanf("%d",&userGameMode); + fpurge(stdin); + + if (userGameMode == PlayerVsPlayer) { + [ticTacToe setMode:PlayerVsPlayer]; + modeSet = YES; + } + else if (userGameMode == PlayerVsComputer){ + [ticTacToe setMode:PlayerVsComputer]; + modeSet = YES; + } + else if (userGameMode == ComputerVsComputer){ + [ticTacToe setMode:ComputerVsComputer]; + modeSet = YES; + } + else { + NSLog(@"Invalid game mode."); + } + } + + //set difficulty + if ([ticTacToe getMode] == PlayerVsComputer) { + BOOL difficultySet = NO; + while (difficultySet == NO && [ticTacToe getMode] != 1) { + NSLog(@"Choose a difficulty."); + NSLog(@" 1) Easy"); + NSLog(@" 2) Medium"); + NSLog(@" 3) Hard"); + int userDifficulty; + scanf("%d",&userDifficulty); + fpurge(stdin); + + if (userDifficulty == Easy) { + [ticTacToe setDifficulty:Easy]; + difficultySet = YES; + } + else if (userDifficulty == Medium){ + [ticTacToe setDifficulty:Medium]; + difficultySet = YES; + } + else if (userDifficulty == Hard){ + [ticTacToe setDifficulty:Hard]; + difficultySet = YES; + } + } + } + //set game size + if ([ticTacToe getMode] == PlayerVsPlayer) { + BOOL gameSizeSet = NO; + while (gameSizeSet == NO) { + NSLog(@"Set a game size from 3-10, fool!:"); + int userGameSize; + scanf("%d",&userGameSize); + fpurge(stdin); + + if (userGameSize >=3 && userGameSize <= 10) { + [ticTacToe setGameSize:userGameSize]; + gameSizeSet = YES; + } + else{ + NSLog(@"Invalid size."); + } + } + } + else{ + [ticTacToe setGameSize:3]; //Computer only works with game size of 3 + } + + [ticTacToe setupGame]; + + [MyTicTacToeGame printTutorialBoard:ticTacToe]; + + while (![ticTacToe checkWin] && ![ticTacToe checkDraw]) { +// NSLog(@"%@", [TicTacToeRowGenerator allLinesForDirection:Diagonal withGame:[ticTacToe getGameBoard]]); + [ticTacToe turn]; + [MyTicTacToeGame printBoard:ticTacToe]; + } + + if ([ticTacToe getWin]) { + if ([ticTacToe getTurnCount] % 2 != 0) { + NSLog(@"Player ~X Wins!"); + } + else{ + NSLog(@"Player ~O Wins!"); + } + } + else{ + NSLog(@"It's a draw."); + } } + return 0; } + diff --git a/TicTacToe/unit-0-assessment b/TicTacToe/unit-0-assessment new file mode 160000 index 0000000..70549bd --- /dev/null +++ b/TicTacToe/unit-0-assessment @@ -0,0 +1 @@ +Subproject commit 70549bd8f68215e89b1c886a1723c3addc43f99f