diff --git a/connect4.c b/connect4.c index dd75c83..28a0955 100644 --- a/connect4.c +++ b/connect4.c @@ -45,16 +45,6 @@ extern char _binary_LICENSE_end[]; int main( int argc, char *argv[] ){ // Initialise variables - wins_t wins = { - .count0 = { - .total = 0, - .vertical = 0, - .horizontal = 0, - .diagonalUp = 0, - .diagonalDown = 0, - }, - }; - wins.count1 = wins.count0; board_t playboard = { .player = 0, .rows = BOARD_HEIGHT, @@ -148,18 +138,29 @@ int main( int argc, char *argv[] ){ "under certain condtions. See `%s --license`\n", argv[0] ); // board, innit? + wins_t wins = { + .count0 = { + .total = 0, + .vertical = 0, + .horizontal = 0, + .diagonalUp = 0, + .diagonalDown = 0, + }, + }; + wins.count1 = wins.count0; + // Allocate the board playboard.height = calloc( playboard.columns, sizeof(int) ); - playboard.column = calloc( playboard.columns, sizeof(int) ); - wins.win0 = calloc( playboard.columns, sizeof(int) ); - wins.win1 = calloc( playboard.columns, sizeof(int) ); - wins.same.vertical2 = calloc( playboard.columns, sizeof(int) ); - wins.same.horizontal2 = calloc( playboard.columns, sizeof(int) ); - wins.same.diagonalUp2 = calloc( playboard.columns, sizeof(int) ); - wins.same.diagonalDown2 = calloc( playboard.columns, sizeof(int) ); - wins.same.vertical4 = calloc( playboard.columns, sizeof(int) ); - wins.same.horizontal4 = calloc( playboard.columns, sizeof(int) ); - wins.same.diagonalUp4 = calloc( playboard.columns, sizeof(int) ); - wins.same.diagonalDown4 = calloc( playboard.columns, sizeof(int) ); + playboard.column = calloc( playboard.columns, sizeof(column_t) ); + wins.win0 = calloc( playboard.columns, sizeof(column_t) ); + wins.win1 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.vertical2 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.horizontal2 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.diagonalUp2 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.diagonalDown2 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.vertical4 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.horizontal4 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.diagonalUp4 = calloc( playboard.columns, sizeof(column_t) ); + wins.same.diagonalDown4 = calloc( playboard.columns, sizeof(column_t) ); initBoard( playboard ); // Begin loopin for(;; playboard.player = !playboard.player ){ diff --git a/logic.c b/logic.c index 456c98f..4e0df6b 100644 --- a/logic.c +++ b/logic.c @@ -62,34 +62,30 @@ void calcWins( const int column ){ // First the simplest win, the humble tower - wins->count0.vertical = 0; - wins->count1.vertical = 0; // Check for lil towers wins->same.vertical2 [ column ] = ~( board.column [ column ] ^ board.column [ column ] >> 1 ) & safeHeightMask( board.height [ column ] - 1 ); - // Actually check for win - wins->same.vertical4 [ column ] = + // Actually check for wins + column_t newcolumn = wins->same.vertical2 [ column ] & wins->same.vertical2 [ column ] >> 1 & wins->same.vertical2 [ column ] >> 2; - // Count 'em - for( int i = 0; i < board.columns; i++ ){ - wins->count0.vertical += __builtin_popcount( - wins->same.vertical4 [ i ] & ~board.column [ i ] - ); - wins->count1.vertical += __builtin_popcount( - wins->same.vertical4 [ i ] & board.column [ i ] - ); + // Count 'em if there's a new one + if( wins->same.vertical4 [ column ] != newcolumn ){ + if( + ( newcolumn + ^ wins->same.vertical4 [ column ] + ) & board.column [ column ] + ){ + wins->count1.vertical ++; + } else { + wins->count0.vertical ++; + } + wins->same.vertical4 [ column ] = newcolumn; } // Now the rest of the wins - wins->count0.horizontal = 0; - wins->count1.horizontal = 0; - wins->count0.diagonalUp = 0; - wins->count1.diagonalUp = 0; - wins->count0.diagonalDown = 0; - wins->count1.diagonalDown = 0; // First connect 2 for( int i = top( column - 1, 0 ); @@ -125,38 +121,54 @@ void calcWins( i < bottom( column + 1, board.columns - 3 ); i++ ){ - wins->same.horizontal4 [ i ] = + newcolumn = wins->same.horizontal2 [ i ] & wins->same.horizontal2 [ i + 1 ] & wins->same.horizontal2 [ i + 2 ]; - wins->same.diagonalUp4 [ i ] = + if( wins->same.horizontal4 [ i ] != newcolumn ){ + if( + ( newcolumn + ^ wins->same.horizontal4 [ i ] + ) & board.column [ i ] + ){ + wins->count1.horizontal++; + } else { + wins->count0.horizontal++; + } + wins->same.horizontal4 [ i ] = newcolumn; + } + newcolumn = wins->same.diagonalUp2 [ i ] & wins->same.diagonalUp2 [ i + 1 ] >> 1 & wins->same.diagonalUp2 [ i + 2 ] >> 2; - wins->same.diagonalDown4 [ i ] = + if( wins->same.diagonalUp4 [ i ] != newcolumn ){ + if( + ( newcolumn + ^ wins->same.diagonalUp4 [ i ] + ) & board.column [ i ] + ){ + wins->count1.diagonalUp++; + } else { + wins->count0.diagonalUp++; + } + wins->same.diagonalUp4 [ i ] = newcolumn; + } + newcolumn = wins->same.diagonalDown2 [ i ] & wins->same.diagonalDown2 [ i + 1 ] << 1 & wins->same.diagonalDown2 [ i + 2 ] << 2; - } - for( int i = 0; i < board.columns - 3; i++ ){ - wins->count0.horizontal += __builtin_popcount( - wins->same.horizontal4 [ i ] & ~board.column [ i ] - ); - wins->count1.horizontal += __builtin_popcount( - wins->same.horizontal4 [ i ] & board.column [ i ] - ); - wins->count0.diagonalUp += __builtin_popcount( - wins->same.diagonalUp4 [ i ] & ~board.column [ i ] - ); - wins->count1.diagonalUp += __builtin_popcount( - wins->same.diagonalUp4 [ i ] & board.column [ i ] - ); - wins->count0.diagonalDown += __builtin_popcount( - wins->same.diagonalDown4 [ i ] & ~board.column [ i ] - ); - wins->count1.diagonalDown += __builtin_popcount( - wins->same.diagonalDown4 [ i ] & board.column [ i ] - ); + if( wins->same.diagonalDown4 [ i ] != newcolumn ){ + if( + ( newcolumn + ^ wins->same.diagonalDown4 [ i ] + ) & board.column [ i ] + ){ + wins->count1.diagonalDown++; + } else { + wins->count0.diagonalDown++; + } + wins->same.diagonalDown4 [ i ] = newcolumn; + } } wins->count0.total = wins->count0.vertical