Compare commits

...

3 commits

4 changed files with 35 additions and 9 deletions

View file

@ -114,7 +114,7 @@ int main( int argc, char *argv[] ){
"\n" "\n"
" -o file --output file Ouput moves taken in game to file\n" " -o file --output file Ouput moves taken in game to file\n"
"\n" "\n"
" --slow-calcwins Use the 32bit reference implementation of calcWins()\n" " --slow-calcwins Use the reference implementation of calcWins()\n"
" --random-moves Play random moves instead of asking for input\n" " --random-moves Play random moves instead of asking for input\n"
); );
return 0; return 0;
@ -150,7 +150,7 @@ int main( int argc, char *argv[] ){
fprintf( stderr, "ERR: AMOUT OF ROWS MUST BE AT LEAST 1\n" ); fprintf( stderr, "ERR: AMOUT OF ROWS MUST BE AT LEAST 1\n" );
return -1; return -1;
} }
#define ROWOVERFLOW (rowsint_t)( sizeof(column_t) * CHAR_BIT ) #define ROWOVERFLOW (rowsint_t)( sizeof(column_t) * CHAR_BIT - 1 )
if( playboard.rows >= ROWOVERFLOW ){ if( playboard.rows >= ROWOVERFLOW ){
fprintf( stderr, fprintf( stderr,
"ERR: AMOUT OF ROWS MUST BE LESS THAN %d\n", ROWOVERFLOW "ERR: AMOUT OF ROWS MUST BE LESS THAN %d\n", ROWOVERFLOW

View file

@ -18,6 +18,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdbit.h> #include <stdbit.h>
#include <stdio.h>
#include "logic.h" #include "logic.h"
#include "macros.h" #include "macros.h"
@ -43,7 +44,8 @@ static void updateTotal( wincount_t *count ){
// popcount for a column // popcount for a column
static winint_t popcnt_column( column_t column ){ static winint_t popcnt_column( column_t column ){
winint_t i = (winint_t)stdc_count_ones( column ); winint_t i = (winint_t)__builtin_popcountg( (uint64_t)column );
//if( i > 32 ) printf( "%d %lb", i, column ); // TODO: REMOVE
return i; return i;
} }
@ -119,6 +121,7 @@ void calcWins_slow( board_t *boardptr ){
& safeHeightMask( boardptr->height[ column + 1 ] ) & safeHeightMask( boardptr->height[ column + 1 ] )
& safeHeightMask( boardptr->height[ column + 2 ] ) & safeHeightMask( boardptr->height[ column + 2 ] )
& safeHeightMask( boardptr->height[ column + 3 ] ) & safeHeightMask( boardptr->height[ column + 3 ] )
& ( ( (column_t)1 << (column_t)boardptr->rows ) - (column_t)1 )
); );
boardptr->count1.horizontal += popcnt_column( boardptr->count1.horizontal += popcnt_column(
boardptr->column[ column ] boardptr->column[ column ]
@ -136,6 +139,7 @@ void calcWins_slow( board_t *boardptr ){
& safeHeightMask( boardptr->height[ column + 1 ] - 1 ) & safeHeightMask( boardptr->height[ column + 1 ] - 1 )
& safeHeightMask( boardptr->height[ column + 2 ] - 2 ) & safeHeightMask( boardptr->height[ column + 2 ] - 2 )
& safeHeightMask( boardptr->height[ column + 3 ] - 3 ) & safeHeightMask( boardptr->height[ column + 3 ] - 3 )
& ( ( (column_t)1 << (column_t)boardptr->rows ) - (column_t)1 )
); );
boardptr->count1.diagonalUp += popcnt_column( boardptr->count1.diagonalUp += popcnt_column(
boardptr->column[ column ] boardptr->column[ column ]
@ -158,6 +162,7 @@ void calcWins_slow( board_t *boardptr ){
boardptr->height[ column + 3 ] + 3 boardptr->height[ column + 3 ] + 3
) )
) )
& ( ( (column_t)1 << (column_t)boardptr->rows ) - (column_t)1 )
); );
boardptr->count1.diagonalDown += popcnt_column( boardptr->count1.diagonalDown += popcnt_column(
boardptr->column[ column ] boardptr->column[ column ]

View file

@ -25,7 +25,7 @@ FLAGS += -Wdisabled-optimization
FLAGS += -fanalyzer FLAGS += -fanalyzer
# These flags are because of the compiler otherwise giving too much warning # These flags are because of the compiler otherwise giving too much warning
FLAGS += -Wno-sign-conversion FLAGS += -Wno-sign-conversion
#FLAGS += -Wformat-truncation=0 FLAGS += -Wformat-truncation=0
# Compile flag for defining GITHASH to put at the end of the version string # Compile flag for defining GITHASH to put at the end of the version string
GITFLAG = -D'GITHASH=$(shell git rev-parse --short=1 HEAD)' GITFLAG = -D'GITHASH=$(shell git rev-parse --short=1 HEAD)'
@ -37,6 +37,7 @@ OUTDIR = out
# The UI to compile for by default using make run # The UI to compile for by default using make run
#UI_TARGET = vt100 #UI_TARGET = vt100
UI_TARGET = ncurses UI_TARGET = ncurses
UI_TESTING = stub
# The URL of the plaintext version of the lisence, for the --license option # The URL of the plaintext version of the lisence, for the --license option
LICENSEURL = https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt LICENSEURL = https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
@ -44,6 +45,10 @@ LICENSEURL = https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# C compiler # C compiler
CC = cc CC = cc
# Test options
TEST_COLUMNS = 1000
TEST_ROWS = 30
.NOTINTERMEDIATE: .NOTINTERMEDIATE:
# Messages to print during different steps in making # Messages to print during different steps in making
@ -65,6 +70,22 @@ run: $(OUTDIR)/connect4_$(UI_TARGET).elf
run_%: $(OUTDIR)/connect4_%.elf run_%: $(OUTDIR)/connect4_%.elf
./$< ./$<
# Show result of test
test: test.diff
# Diff between the tests
test.diff: test.log test.log.slow
diff -y $^ > $@ || tail $@
diff -q $^
# Log of testing fast logic
test.log: $(OUTDIR)/connect4_$(UI_TESTING).elf
./$< -o $@ -c $(TEST_COLUMNS) -r $(TEST_ROWS) --random-moves
# Log of testing slow logic
test.log.slow: $(OUTDIR)/connect4_$(UI_TESTING).elf
./$< -o $@ -c $(TEST_COLUMNS) -r $(TEST_ROWS) --random-moves --slow-calcWins
# Compile specifically the ncurses version # Compile specifically the ncurses version
# This one's special because it needs -lncursesw # This one's special because it needs -lncursesw
$(OUTDIR)/connect4_ncurses.elf: $(addprefix $(OBJDIR)/,ui_ncurses.o logic.o connect4.o LICENSE.o) $(OUTDIR)/connect4_ncurses.elf: $(addprefix $(OBJDIR)/,ui_ncurses.o logic.o connect4.o LICENSE.o)

10
types.h
View file

@ -5,13 +5,13 @@
#include <limits.h> #include <limits.h>
#include "config.h" #include "config.h"
// Use fastest available ints unless it's 64 bits because that uses more memory // Use fastest available ints unless it's 64 bits because that is doing silly
#if INT_FAST16_MAX == INT_FAST64_MAX #if INT_FAST16_MAX == INT_FAST64_MAX
typedef int rowsint_t; typedef int rowsint_t;
typedef unsigned columnsint_t; typedef unsigned columnsint_t;
#define QUITCOLUMN UINT_MAX #define QUITCOLUMN UINT_MAX
typedef unsigned winint_t; typedef unsigned winint_t;
typedef uintmax_t column_t; typedef unsigned column_t;
#else #else
typedef int_fast8_t rowsint_t; typedef int_fast8_t rowsint_t;
typedef uint_fast8_t columnsint_t; typedef uint_fast8_t columnsint_t;