Skip to content

Instantly share code, notes, and snippets.

@bharath2020
Last active December 29, 2015 10:52
Show Gist options
  • Save bharath2020/2dbc766c73ede9c044fa to your computer and use it in GitHub Desktop.
Save bharath2020/2dbc766c73ede9c044fa to your computer and use it in GitHub Desktop.
TTBoard.swift class from Tic-Tac-Toe
//
// 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