lundi 28 septembre 2015

How do I deal with having a massive amount of conditions on an if-than statement?

I recently built a Tic Tac Toe game in Objective-C, while focusing on trying to make my code as short and clean as possible (as I'm relatively new to programming, this is my first time focusing on making something efficient/readable instead of just making it work at any cost)

For the most part, I was able to make my code short and efficient enough that I was happy with it - except for the part of the checkWin function that checks if either X or O has won the game

I have an NSArray Object called "BoardState", with the indexes 0-8 corresponding to the 9 spots on the board like so

0 1 2
3 4 5
6 7 8

When an index is set to 0, it's considered blank. 1 is X, 2 is O.

However, the only way I could figure out how to check if X or O has won is to manually go over the entire board with an if statement and check every possibility, like so

if  (
    ([_boardState[0] isEqual:@1]  &&
     [_boardState[1] isEqual:@1]  &&
     [_boardState[2] isEqual:@1]) ||

    ([_boardState[3] isEqual:@1]  &&
     [_boardState[4] isEqual:@1]  &&
     [_boardState[5] isEqual:@1]) ||

    ([_boardState[6] isEqual:@1]  &&
     [_boardState[7] isEqual:@1]  &&
     [_boardState[8] isEqual:@1]) ||

    ([_boardState[0] isEqual:@1]  &&
     [_boardState[3] isEqual:@1]  &&
     [_boardState[6] isEqual:@1]) ||

    ([_boardState[1] isEqual:@1]  &&
     [_boardState[4] isEqual:@1]  &&
     [_boardState[7] isEqual:@1]) ||

    ([_boardState[2] isEqual:@1]  &&
     [_boardState[5] isEqual:@1]  &&
     [_boardState[8] isEqual:@1]) ||

    ([_boardState[0] isEqual:@1]  &&
     [_boardState[4] isEqual:@1]  &&
     [_boardState[8] isEqual:@1]) ||

    ([_boardState[2] isEqual:@1]  &&
     [_boardState[4] isEqual:@1]  &&
     [_boardState[6] isEqual:@1])
     ){
    [xWins show];
    [self overWriteBoardState];
}

then once again, with O, almost exactly the same thing.

if  (
     ([_boardState[0] isEqual:@2]  &&
      [_boardState[1] isEqual:@2]  &&
      [_boardState[2] isEqual:@2]) ||

     ([_boardState[3] isEqual:@2]  &&
      [_boardState[4] isEqual:@2]  &&
      [_boardState[5] isEqual:@2]) ||

     ([_boardState[6] isEqual:@2]  &&
      [_boardState[7] isEqual:@2]  &&
      [_boardState[8] isEqual:@2]) ||

     ([_boardState[0] isEqual:@2]  &&
      [_boardState[3] isEqual:@2]  &&
      [_boardState[6] isEqual:@2]) ||

     ([_boardState[1] isEqual:@2]  &&
      [_boardState[4] isEqual:@2]  &&
      [_boardState[7] isEqual:@2]) ||

     ([_boardState[2] isEqual:@2]  &&
      [_boardState[5] isEqual:@2]  &&
      [_boardState[8] isEqual:@2]) ||

     ([_boardState[0] isEqual:@2]  &&
      [_boardState[4] isEqual:@2]  &&
      [_boardState[8] isEqual:@2]) ||

     ([_boardState[2] isEqual:@2]  &&
      [_boardState[4] isEqual:@2]  &&
      [_boardState[6] isEqual:@2])
     ){
    [oWins show];
    [self overWriteBoardState];
}

As a bonus, my overWriteBoardState function that reset the board to a blank slate which cannot be modified anymore. This could also be more efficient

-(void)overWriteBoardState {
    self.boardState[0] = @3;
    self.boardState[1] = @3;
    self.boardState[2] = @3;
    self.boardState[3] = @3;
    self.boardState[4] = @3;
    self.boardState[5] = @3;
    self.boardState[6] = @3;
    self.boardState[7] = @3;
    self.boardState[8] = @3;
}

How else could I structure this as to avoid these massive piles of repeated lines? Any help or tips is appreciated - thanks!

Aucun commentaire:

Enregistrer un commentaire