483 lines
14 KiB
Objective-C
483 lines
14 KiB
Objective-C
//
|
|
// RIAppDelegate.m
|
|
// Tic-Tac-Toe
|
|
//
|
|
// Created by RUSlan on 23.03.14.
|
|
// Copyright (c) 2014 RUSlan. All rights reserved.
|
|
//
|
|
|
|
#import "RIAppDelegate.h"
|
|
|
|
|
|
NSString *playerMove;
|
|
NSString *computerMove;
|
|
NSString *player1Move;
|
|
NSString *player2Move;
|
|
|
|
bool gameWasEnded;
|
|
bool computerPlaysFirst;
|
|
bool firstPlayerMove;
|
|
bool twoPlayerMode;
|
|
|
|
NSInteger wins;
|
|
NSInteger loses;
|
|
NSInteger draws;
|
|
NSInteger player1Wins;
|
|
NSInteger player2Wins;
|
|
NSInteger dualDraws;
|
|
|
|
|
|
@implementation RIAppDelegate
|
|
|
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
|
{
|
|
playerMove = [NSString new];
|
|
computerMove = [NSString new];
|
|
player1Move = [NSString new];
|
|
player2Move = [NSString new];
|
|
|
|
player1Move = @"X";
|
|
player2Move = @"O";
|
|
|
|
|
|
gameWasEnded = false;
|
|
|
|
wins = 0;
|
|
loses = 0;
|
|
draws = 0;
|
|
player1Wins = 0;
|
|
player2Wins = 0;
|
|
dualDraws = 0;
|
|
|
|
[_ButtonChangeFirstMove selectItemAtIndex: 0];
|
|
[self FirstMoveChange: NULL];
|
|
|
|
[self NewGame: NULL];
|
|
}
|
|
|
|
- (IBAction)NewGame:(id)sender {
|
|
[_Text setStringValue: @"New Game"];
|
|
|
|
firstPlayerMove = true;
|
|
|
|
[_ButtonChangeFirstMove setEnabled: true];
|
|
|
|
[self StatsUpdate: NULL];
|
|
gameWasEnded = false;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
[[_Buttons cellAtRow: i column: j] setTitle: @""];
|
|
}
|
|
}
|
|
if (computerPlaysFirst) {
|
|
computerMv(_Buttons, _Text);
|
|
}
|
|
}
|
|
|
|
- (IBAction)ClickMatrix:(id)sender {
|
|
|
|
if (gameWasEnded) {
|
|
[self NewGame: NULL];
|
|
}
|
|
else {
|
|
[_Text setStringValue: @""];
|
|
|
|
[_ButtonChangeFirstMove setEnabled: false];
|
|
|
|
if ([[[sender selectedCell] title] compare: @""]) {
|
|
[_Text setStringValue: @"Illegal move!"];
|
|
}
|
|
else {
|
|
[self Checking];
|
|
if (!gameWasEnded) {
|
|
[self CheckingDraw];
|
|
}
|
|
if (twoPlayerMode) {
|
|
[[sender selectedCell] setTitle: (firstPlayerMove) ? player1Move : player2Move];
|
|
[self Checking];
|
|
if (!gameWasEnded) {
|
|
[self CheckingDraw];
|
|
}
|
|
firstPlayerMove = !firstPlayerMove;
|
|
}
|
|
else {
|
|
[[sender selectedCell] setTitle: playerMove];
|
|
[self Checking];
|
|
if (!gameWasEnded) {
|
|
[self CheckingDraw];
|
|
}
|
|
if (!gameWasEnded) {
|
|
computerMv(sender, _Text);
|
|
[self Checking];
|
|
if (!gameWasEnded) {
|
|
[self CheckingDraw];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (IBAction)Checking {
|
|
if ( (cellEq(_Buttons, 0, 0, 1, 1) && cellEq(_Buttons, 0, 0, 2, 2)) ||
|
|
(cellEq(_Buttons, 0, 2, 1, 1) && cellEq(_Buttons, 0, 2, 2, 0)) ) {
|
|
if (twoPlayerMode) {
|
|
if ([[_Buttons cellAtRow: 1 column: 1] title] == player1Move) {
|
|
[_Text setStringValue: @"Player 1 won!"];
|
|
player1Wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Player 2 won!"];
|
|
player2Wins++;
|
|
}
|
|
}
|
|
else {
|
|
if ([[_Buttons cellAtRow: 1 column: 1] title] == playerMove) {
|
|
[_Text setStringValue: @"Player won!"];
|
|
wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Computer won!"];
|
|
loses++;
|
|
}
|
|
}
|
|
gameWasEnded = true;
|
|
}
|
|
for (int i = 0; i < 3; i++) {
|
|
if ( cellEq(_Buttons, 0, i, 1, i) && cellEq(_Buttons, 0, i, 2, i) ) {
|
|
if (twoPlayerMode) {
|
|
if ([[_Buttons cellAtRow: 0 column: i] title] == player1Move) {
|
|
[_Text setStringValue: @"Player 1 won!"];
|
|
player1Wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Player 2 won!"];
|
|
player2Wins++;
|
|
}
|
|
}
|
|
else {
|
|
if ([[_Buttons cellAtRow: 0 column: i] title] == playerMove) {
|
|
[_Text setStringValue: @"Player won!"];
|
|
wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Computer won!"];
|
|
loses++;
|
|
}
|
|
|
|
}
|
|
gameWasEnded = true;
|
|
break;
|
|
}
|
|
if ( cellEq(_Buttons, i, 0, i, 1) && cellEq(_Buttons, i, 0, i, 2) ) {
|
|
if (twoPlayerMode) {
|
|
if ([[_Buttons cellAtRow: i column: 0] title] == player1Move) {
|
|
[_Text setStringValue: @"Player 1 won!"];
|
|
player1Wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Player 2 won!"];
|
|
player2Wins++;
|
|
}
|
|
}
|
|
else {
|
|
if ([[_Buttons cellAtRow: i column: 0] title] == playerMove) {
|
|
[_Text setStringValue: @"Player won!"];
|
|
wins++;
|
|
}
|
|
else {
|
|
[_Text setStringValue: @"Computer won!"];
|
|
loses++;
|
|
}
|
|
}
|
|
gameWasEnded = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (IBAction)CheckingDraw {
|
|
bool full = true;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
full = full && ![[[_Buttons cellAtRow: i column: j] title] isEqual: @""];
|
|
}
|
|
}
|
|
|
|
if (full) {
|
|
[_Text setStringValue: @"Draw!"];
|
|
gameWasEnded = true;
|
|
if (twoPlayerMode) {
|
|
dualDraws++;
|
|
}
|
|
else {
|
|
draws++;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (IBAction)FirstMoveChange:(id)sender {
|
|
|
|
switch ([_ButtonChangeFirstMove indexOfSelectedItem]) {
|
|
case 0:
|
|
computerPlaysFirst = false;
|
|
twoPlayerMode = false;
|
|
break;
|
|
case 1:
|
|
computerPlaysFirst = true;
|
|
twoPlayerMode = false;
|
|
break;
|
|
case 2:
|
|
computerPlaysFirst = false;
|
|
twoPlayerMode = true;
|
|
firstPlayerMove = true;
|
|
break;
|
|
}
|
|
changeXO();
|
|
|
|
[self NewGame: NULL];
|
|
[self StatsUpdate: NULL];
|
|
}
|
|
|
|
- (IBAction)StatsUpdate:(id)sender {
|
|
NSInteger percentW;
|
|
NSInteger percentL;
|
|
NSInteger games;
|
|
if (twoPlayerMode) {
|
|
games = wins + loses + draws;
|
|
|
|
if (games) {
|
|
percentW = round( ((double)wins)/(games) * 100 );
|
|
percentL = round( ((double)loses)/(games) * 100 );
|
|
}
|
|
else {
|
|
percentW = 0;
|
|
percentL = 0;
|
|
}
|
|
[[_Stats cellAtRow: 0 column: 0] setStringValue: @"P1 wins:"];
|
|
[[_Stats cellAtRow: 1 column: 0] setStringValue: @"P2 wins:"];
|
|
[[_Stats cellAtRow: 2 column: 0] setStringValue: @"Draws:"];
|
|
[[_Stats cellAtRow: 3 column: 0] setStringValue: @"P1 Win rate:"];
|
|
[[_Stats cellAtRow: 4 column: 0] setStringValue: @"P2 Win rate:"];
|
|
|
|
[[_Stats cellAtRow: 0 column: 1] setIntegerValue: player1Wins];
|
|
[[_Stats cellAtRow: 1 column: 1] setIntegerValue: player2Wins];
|
|
[[_Stats cellAtRow: 2 column: 1] setIntegerValue: dualDraws];
|
|
[[_Stats cellAtRow: 3 column: 1] setStringValue:
|
|
[NSString stringWithFormat: @"%ld%c", (long)percentW, '%']];
|
|
[[_Stats cellAtRow: 4 column: 1] setStringValue:
|
|
[NSString stringWithFormat: @"%ld%c", (long)percentL, '%']];
|
|
}
|
|
else {
|
|
games = wins + loses + draws;
|
|
|
|
if (games) {
|
|
percentW = round( ((double)wins)/(games) * 100 );
|
|
percentL = round( ((double)loses)/(games) * 100 );
|
|
}
|
|
else {
|
|
percentW = 0;
|
|
percentL = 0;
|
|
}
|
|
[[_Stats cellAtRow: 0 column: 0] setStringValue: @"Wins:"];
|
|
[[_Stats cellAtRow: 1 column: 0] setStringValue: @"Loses:"];
|
|
[[_Stats cellAtRow: 2 column: 0] setStringValue: @"Draws:"];
|
|
[[_Stats cellAtRow: 3 column: 0] setStringValue: @"Win rate:"];
|
|
[[_Stats cellAtRow: 4 column: 0] setStringValue: @"Lose rate:"];
|
|
|
|
|
|
[[_Stats cellAtRow: 0 column: 1] setIntegerValue: wins];
|
|
[[_Stats cellAtRow: 1 column: 1] setIntegerValue: loses];
|
|
[[_Stats cellAtRow: 2 column: 1] setIntegerValue: draws];
|
|
[[_Stats cellAtRow: 3 column: 1] setStringValue:
|
|
[NSString stringWithFormat: @"%ld%c", (long)percentW, '%']];
|
|
[[_Stats cellAtRow: 4 column: 1] setStringValue:
|
|
[NSString stringWithFormat: @"%ld%c", (long)percentL, '%']];
|
|
}
|
|
}
|
|
|
|
|
|
bool cellEq(id array, int firstRow, int firstColumn, int secondRow, int secondColumn) {
|
|
|
|
if (![[[array cellAtRow: firstRow column: firstColumn] title] isEqual: @""]) {
|
|
if ([[array cellAtRow: firstRow column: firstColumn] title] ==
|
|
[[array cellAtRow: secondRow column: secondColumn] title]) {
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void computerMv(id array, id Text) {
|
|
|
|
id cellC = NULL;
|
|
id cellP = NULL;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
if ((cellEq(array, i, 0, i, 1)) &&
|
|
([[[array cellAtRow: i column: 2] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: i column: 0] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: i column: 2];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: i column: 2];
|
|
}
|
|
break;
|
|
}
|
|
else if ((cellEq(array, i, 0, i, 2)) &&
|
|
([[[array cellAtRow: i column: 1] title] isEqual: @""]))
|
|
{
|
|
if (([[[array cellAtRow: i column: 0] title] isEqual: computerMove])) {
|
|
cellC = [array cellAtRow: i column: 1];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: i column: 1];
|
|
}
|
|
break;
|
|
}
|
|
else if ((cellEq(array, i, 2, i, 1)) &&
|
|
([[[array cellAtRow: i column: 0] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: i column: 1] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: i column: 0];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: i column: 0];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
for (int i = 0; i < 3; i++) {
|
|
if ((cellEq(array, 0, i, 1, i)) &&
|
|
([[[array cellAtRow: 2 column: i] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: i] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 2 column: i];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 2 column: i];
|
|
}
|
|
break;
|
|
}
|
|
else if ((cellEq(array, 0, i, 2, i)) &&
|
|
([[[array cellAtRow: 1 column: i] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: i] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 1 column: i];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 1 column: i];
|
|
}
|
|
break;
|
|
}
|
|
else if ((cellEq(array, 2, i, 1, i)) &&
|
|
([[[array cellAtRow: 0 column: i] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 2 column: i] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 0 column: i];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 0 column: i];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((cellEq(array, 0, 0, 1, 1)) &&
|
|
([[[array cellAtRow: 2 column: 2] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: 0] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 2 column: 2];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 2 column: 2];
|
|
}
|
|
}
|
|
else if ((cellEq(array, 0, 0, 2, 2)) &&
|
|
([[[array cellAtRow: 1 column: 1] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: 0] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 1 column: 1];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 1 column: 1];
|
|
}
|
|
}
|
|
else if ((cellEq(array, 2, 2, 1, 1)) &&
|
|
([[[array cellAtRow: 0 column: 0] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 2 column: 2] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 0 column: 0];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 0 column: 0];
|
|
}
|
|
}
|
|
else if ((cellEq(array, 0, 2, 1, 1)) &&
|
|
([[[array cellAtRow: 2 column: 0] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: 2] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 2 column: 0];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 2 column: 0];
|
|
}
|
|
}
|
|
else if ((cellEq(array, 2, 0, 0, 2)) &&
|
|
([[[array cellAtRow: 1 column: 1] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 0 column: 2] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 1 column: 1];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 1 column: 1];
|
|
}
|
|
}
|
|
else if ((cellEq(array, 2, 0, 1, 1)) &&
|
|
([[[array cellAtRow: 0 column: 2] title] isEqual: @""]))
|
|
{
|
|
if ([[[array cellAtRow: 1 column: 1] title] isEqual: computerMove]) {
|
|
cellC = [array cellAtRow: 0 column: 2];
|
|
}
|
|
else {
|
|
cellP = [array cellAtRow: 0 column: 2];
|
|
}
|
|
}
|
|
|
|
if (cellC) {
|
|
[cellC setTitle: computerMove];
|
|
}
|
|
else if (cellP) {
|
|
[cellP setTitle: computerMove];
|
|
}
|
|
else {
|
|
while (true) {
|
|
int i = random() % 3;
|
|
int j = random() % 3;
|
|
|
|
if ([[[array cellAtRow: i column: j] title] isEqualToString: @""]) {
|
|
[[array cellAtRow: i column: j] setTitle: computerMove];
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void changeXO()
|
|
{
|
|
playerMove = (computerPlaysFirst) ? @"O" : @"X";
|
|
computerMove = (computerPlaysFirst) ? @"X" : @"O";
|
|
}
|
|
|
|
@end
|
|
|