Last active
December 29, 2015 10:52
-
-
Save bharath2020/2dbc766c73ede9c044fa to your computer and use it in GitHub Desktop.
TTBoard.swift class from Tic-Tac-Toe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TTBoard.swift | |
// Tic-Tac-Toe-Swift | |
// | |
// Created by Bharath Booshan on 9/12/15. | |
// Copyright (c) 2015 FeatherTouch. All rights reserved. | |
// | |
import Foundation | |
import UIKit | |
enum BoardState { | |
case Win | |
case Complete | |
case InComplete | |
} | |
let NOT_OCCUPIED = -1 | |
//represetn 3x3 matrix in a single dimension | |
//The values represents the different winning combinations of a Tic-Tac-Toe board | |
let win:[Int] = [0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6]; | |
final class TTBoard { | |
private var board : [Int] = [] //represents the 9 cells in tic-tac-toe | |
private var totalPiecesOnBoard = 0 //represents total number of player's pawns on the board | |
private var emptySpots : [Int] = [] // represents total numbe of empty cells on the board | |
let boardID : String // a board Identifier | |
//By default, the board should be cleared and should not have any pawns on the board | |
init(boardIDString : String) { | |
self.boardID = boardIDString | |
for pos in 0...8 { | |
board.append( NOT_OCCUPIED ) | |
emptySpots.append(pos) | |
} | |
} | |
func getBoardID() -> String { | |
return self.boardID | |
} | |
//position : Place a pawn on the board at a given 'position' | |
//playerCode: playerCode represents the player who is occupying the position | |
// Return : board state after placing the pawn at given 'position' | |
// Win - if the player wins as a result of placing this pawn | |
// Incomplete - if there is still empty places | |
// Complete - There are no empty places and the game has been tied, as neither of the player has won | |
final func markPosition(position : Int , playerCode : Int ) -> BoardState { | |
assert(position < 9, "Position greater than 9 while marking position") | |
if board[position] != NOT_OCCUPIED { | |
return .InComplete | |
} | |
board[position] = playerCode | |
removePositionFromEmptySlot(position) | |
totalPiecesOnBoard++ | |
let boardState:Int = winner() | |
if boardState != 0 { | |
return .Win | |
} | |
else if isBoardComplete() { | |
return .Complete | |
} | |
else{ | |
return .InComplete | |
} | |
} | |
//Get Array of positions, representing the empty slots on the board | |
func getEmptySpotList() -> [Int] { | |
return Array<Int>(emptySpots) | |
} | |
//when the position is being occupied by player's pawn, remove that position from empty slot list | |
func removePositionFromEmptySlot(position : Int ){ | |
//remove from empty slots | |
if let index = emptySpots.indexOf(position) { | |
emptySpots.removeAtIndex(index) | |
} | |
} | |
//add the give 'position' to empty list | |
func addPositionToEmptySlot(position : Int ){ | |
emptySpots.append(position) | |
} | |
//Rest the position and mark the 'position' as empty | |
func resetPosition( position : Int ){ | |
assert(position<9, "Position greater than 9 while resetting") | |
board[position] = NOT_OCCUPIED | |
addPositionToEmptySlot(position) | |
totalPiecesOnBoard-- | |
} | |
//Return the player code who has won the board | |
func winner( ) -> Int { | |
// 0 1 2 | |
// 3 4 5 | |
// 6 7 8 | |
for index in 0...7 { | |
let baseIndex = index * 3 | |
let valAt0 = board[win[baseIndex]] | |
if( valAt0 != NOT_OCCUPIED && | |
valAt0 == board[win[baseIndex+1]] && | |
valAt0 == board[win[baseIndex+2]]){ | |
return valAt0; | |
} | |
} | |
return 0; | |
} | |
//Retrun true, if the board is empty and no player's pawn is kept on the board | |
func isBoardEmpty() -> Bool { | |
return totalPiecesOnBoard == 0; | |
} | |
//Return true, if there are no empty slots to proceed the play | |
func isBoardComplete() -> Bool { | |
return totalPiecesOnBoard == 9 | |
} | |
//Check if the two boards are equal. | |
func isEqualToBoard( otherBoard : TTBoard ) -> Bool { | |
return boardID == otherBoard.boardID | |
} | |
//Reset the board to clear all the pawns | |
func resetBoard() -> Void { | |
for _ in 0...8 { | |
board.append(NOT_OCCUPIED) | |
} | |
totalPiecesOnBoard=0 | |
} | |
//Deep copy from other board, including player's position, empty slots | |
// | |
func copyBoardFrom(otherBoard: [Int], emptySpotsCopy : [Int] ) -> Void{ | |
let boardCount = otherBoard.count | |
board.removeAll(keepCapacity: true) | |
for position in 0...boardCount-1 { | |
board.append(otherBoard[position]) | |
} | |
emptySpots.removeAll(keepCapacity: true) | |
for val in emptySpotsCopy{ | |
emptySpots.append(val) | |
} | |
} | |
//mimic the copy method of Objective-C to perform a deep copy. | |
func copy() -> TTBoard { | |
let copy = TTBoard(boardIDString: self.boardID) | |
copy.copyBoardFrom(board,emptySpotsCopy: emptySpots) | |
copy.totalPiecesOnBoard = self.totalPiecesOnBoard | |
return copy | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment