From: Laurent MAZET Date: Thu, 23 May 2024 14:12:57 +0000 (+0200) Subject: initial commit X-Git-Tag: v1.0~57 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=f27f7111a48a930eec69df26bebf6dbe63f068c1;p=scrabble.git initial commit --- f27f7111a48a930eec69df26bebf6dbe63f068c1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..214731f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.d +*.ld +*.exe +*.log +*.o diff --git a/board.c b/board.c new file mode 100644 index 0000000..b58c0c4 --- /dev/null +++ b/board.c @@ -0,0 +1,145 @@ +#include +#include +#include + +#include "board.h" +#include "debug.h" + +typedef struct { + int xsize; + int ysize; + float factor; + int length; + int premium; + char *TW; + char *DW; + char *TL; + char *DL; + char *CS; +} board_t; + +board_t _board = +{ + 15, /* xsize */ + 15, /* ysize */ + 1, /* factor */ + 7, /* length */ + 50, /* premium */ + "A1\0A8\0A15\0H1\0H15\0O1\0O8\0O15\0", /* TW */ + "B2\0B14\0C3\0C13\0D4\0D12\0E5\0E11\0K5\0K11\0L4\0L12\0M3\0M13\0N2\0N14\0", /* DW */ + "B6\0B10\0F2\0F6\0F10\0F14\0J2\0J6\0J10\0J14\0N6\0N10\0", /* TL */ + "A4\0A12\0C7\0C9\0D1\0D8\0D15\0G3\0G7\0G9\0G13\0H4\0H12\0I3\0I7\0I9\0I13\0L1\0L8\0L15\0M7\0M9\0O4\0O12\0", /* DL */ + "H8\0" /* CS */ +}; +board_t *board = &_board; + +int contains (char *list, char *str) +{ + while (*list) { + if (strcmp (list, str) == 0) { + return 1; + } + list += strlen (list) + 1; + } + return 0; +} + + +typedef enum { + white = 1, + red, + green, + blue, + cyan, + magenta, + yellow, + black, +} color_t; + +void set_color (color_t color) +{ + int init = 1; + + if (init) { + init_pair (white, COLOR_WHITE, COLOR_BLACK); + init_pair (red, COLOR_BLACK, COLOR_RED); + init_pair (green, COLOR_BLACK, COLOR_GREEN); + init_pair (blue, COLOR_BLACK, COLOR_BLUE); + init_pair (magenta, COLOR_BLACK, COLOR_MAGENTA); + init_pair (yellow, COLOR_BLACK, COLOR_YELLOW); + init_pair (cyan, COLOR_BLACK, COLOR_CYAN); + init_pair (black, COLOR_BLACK, COLOR_WHITE); + init = 0; + } + + attrset (COLOR_PAIR(color)); +} + +char *initboard (void) +{ + char *tab = (char *) malloc (board->xsize * board->ysize); + memset (tab, ' ', board->xsize * board->ysize); + return tab; +} + +void showboard (char *tab, int xoffset, int yoffset, int full) +{ + int x, y; + for (x = -1; x <= board->xsize; x++) { + for (y = -1; y <= board->ysize; y++) { + int c = ' '; + char pos[4] = {0}; + sprintf (pos, "%c%d", 'A' + x, 1 + y); + if ((x == -1) && (y == -1)) { + c = ACS_ULCORNER; + set_color (black); + } else if ((x == board->xsize) && (y== -1)) { + c = ACS_URCORNER; + set_color (black); + } else if ((x == -1) && (y == board->ysize)) { + c = ACS_LLCORNER; + set_color (black); + } else if ((x == board->xsize) && (y == board->ysize)) { + c = ACS_LRCORNER; + set_color (black); + } else if ((x == -1) || (x == board->xsize)) { + c = ACS_VLINE; + set_color (black); + } else if ((y == -1) || (y == board->xsize)) { + c = ACS_HLINE; + set_color (black); + } else { + c = tab[x + y * board->xsize]; + if (c == ' ') { + if (contains (board->TW, pos)) { + c = 'T'; + set_color (red); + } else if (contains (board->DW, pos)) { + c = 'D'; + set_color (magenta); + } else if (contains (board->TL, pos)) { + c = 't'; + set_color (blue); + } else if (contains (board->DL, pos)) { + c = 'd'; + set_color (cyan); + } else if (contains (board->CS, pos)) { + c = 'S'; + set_color (magenta); + } + if (!full) { + c = ' '; + } + } + } + VERBOSE (DEBUG, if ((c < 32) || (c > 255)) printf ("character: %c\n", c)); + if (c) { + mvaddch(yoffset + y, xoffset + x, c); + } + set_color (white); + + } + } +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/board.h b/board.h new file mode 100644 index 0000000..935b411 --- /dev/null +++ b/board.h @@ -0,0 +1,9 @@ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +char *initboard (void); +void showboard (char *tab, int xoffset, int yoffset, int full); + +#endif /* __BOARD_H__ */ + +/* vim: set ts=4 sw=4 et: */ diff --git a/debug.c b/debug.c new file mode 100644 index 0000000..b9eba44 --- /dev/null +++ b/debug.c @@ -0,0 +1,5 @@ +#include "debug.h" + +int verbose = 0; + +/* vim: set ts=4 sw=4 et: */ diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..32dc0ca --- /dev/null +++ b/debug.h @@ -0,0 +1,21 @@ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +/* constants */ + +#define DEBUG 3 +#define INFO 2 +#define WARNING 1 +#define ERROR 0 + +/* macros */ + +#define VERBOSE(level, statement...) do { if (level <= verbose) { statement; } } while(0) + +/* gobal variables */ + +extern int verbose; + +#endif /* __DEBUG_H__ */ + +/* vim: set ts=4 sw=4 et: */ diff --git a/getcomments.pl b/getcomments.pl new file mode 100644 index 0000000..47edf67 --- /dev/null +++ b/getcomments.pl @@ -0,0 +1,85 @@ +#!/usr/bin/perl + +use strict; + +# default value +my $format = "%"; +my $pattern = ""; + +# help message +sub usage() { + + print <) { + my $cmt; + + # process c++ comments + ($cmt, $_) = m{//\s*(.*?)\s*$()} if (m{//} && !m{/\*.*//}); + + # process standard c comments + ($cmt, $_) = m{^.*?/\*\s*(.*?)\s*\*/(.*)}s if (m{/\*.*\*/}s); + + push(@comments, $cmt) if ($cmt); + + # empty buffer if no comment is present + undef($_) if (!m{/[/*]}); + } + + # close file + close (IN); + + # display comment blocks + foreach my $block (@comments) { + if (($block) = ($block =~ /$pattern(.*)/s)) { + ($_ = $format) =~ s/%/$block/gs; + print "$_\n"; + } + } +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..bcdc9c6 --- /dev/null +++ b/makefile @@ -0,0 +1,173 @@ +# Default flags + +CC = gcc + +#INCLUDES = -I../debug -D__MEMORY_ALLOCATION__ +INCLUDES = +OFLAGS = -O4 -Os +#OFLAGS = -O4 -ffast-math -finline-functions +#OFLAGS = -O4 -finline-functions +#OFLAGS += -mtune=pentium3 -mmmx -msse -msse2 -m3dnow +#OFLAGS += -minline-all-stringops -fsingle-precision-constant +#OFLAGS += -malign-double +CFLAGS += -W -Wall -Wextra -g +#CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 +CFLAGS += $(OFLAGS) $(INCLUDES) $(OPTIONS) +LDFLAGS += -g $(OPTIONS) + +LDOPT = linker +ifeq ($(OS),Windows_NT) +#LDLIBS += -lws2_32 +LDOPT = winlnk +endif + + +# Targets + +ALLEXE = +ALLEXE += scrabble + +SHELL = bash + +#MAKE = mingw32-make +MAKEFLAGS += -s +include $(wildcard .makefile) + +# Functions + +TITLE = echo -en "\033[0;1m$(strip $(1))\033[0;0m:\t" +PASS = echo -e "\033[1;32m$(strip $(1))\033[0;0m" +WARN = echo -e "\033[1;33m$(strip $(1))\033[0;0m" +FAIL = echo -e "\033[1;31m$(strip $(1))\033[0;0m" + +MKDIR = mkdir -p $(1) && chmod a+rx,go-w $(1) + +INSTALL = test -d `dirname $(2)` || $(call MKDIR, `dirname $(2)`) && cp -pa $(1) $(2) && chmod a+rX,go-w $(2) + +VALID = $(call TITLE, $(1)) && $(2) && $(call PASS, SUCCESS) || { $(call FAIL, FAILED); test; } + +## Generic rules + +all: depends + $(MAKE) $(ALLEXE:%=%.exe) + +count: + wc $(wildcard *.c *.h) $(MAKEFILE_LIST) + +clean: + $(call TITLE, "Cleaning") + touch clean + rm -f clean $(wildcard *.d *.ld *.log *.o *.test *~ .exec_* gmon.out) + $(call PASS, SUCCESS) + +depends: $(patsubst %.c, %.d, $(wildcard *.c)) $(patsubst %, %.ld, $(ALLEXE)) + +gcovs: + $(MAKE) $(addprefix gcov_,$(ALLEXE)) + +gprofs: + $(MAKE) $(addprefix gprof_,$(ALLEXE)) + +purge: clean + $(call TITLE, "Purging") + touch purge + rm -f purge $(ALLEXE:%=%.exe) + $(call PASS, SUCCESS) + +valgrinds: all + $(MAKE) $(addprefix valgrind_,$(ALLEXE)) + +wipe: purge + $(call TITLE, "Wiping") + touch wipe + rm -f wipe $(wildcard *.gcda *.gcno *.gcov *.glog) + $(call PASS, SUCCESS) + +tests: all + $(MAKE) $(addprefix test_,$(ALLEXE)) + +## Main rules + +include $(wildcard *.d) +include $(wildcard *.ld) + +gcov_%: + $(MAKE) purge + OPTIONS="-coverage -O0" $(MAKE) + $(MAKE) test_$(@:gcov_%=%) + gcov `sed -e 's/\.exe:/.c/;s/\.o/.c/g' $(@:gcov_%=%.ld)` + touch gcov + rm -f gcov $(wildcard *.gcda *.gcno) + $(MAKE) purge + grep '#####' *.c.gcov || true + +gprof_%: + $(MAKE) purge + $(MAKE) depends + OPTIONS="-pg" $(MAKE) ${@:gprof_%=%}.exe + $(MAKE) ${@:gprof_%=%}.test + IFS=$$'\n'; id=1; \ + for test in `cat ${@:gprof_%=%}.test | sed 's,${@:gprof_%=%}.exe,./${@:gprof_%=%}.exe,g'`; do \ + log=${@:gprof_%=%}.prof-$$id.glog; \ + $(call TITLE, test: $$test); \ + echo $$test > $$log; \ + eval $$test >> $$log; \ + [ $$? -eq 0 ] \ + && echo -e "\033[1;32mSUCCESS\033[0;0m" \ + || echo -e "\033[1;31mFAILED\033[0;0m"; \ + [ -f gmon.out ] && { gprof ${@:gprof_%=%}.exe gmon.out >> $$log; rm gmon.out; }; \ + let id++; \ + done; + $(MAKE) purge + +%.test: %.c + $(call TITLE, "Building $@") +# awk '/\/\* *test:.*\*\// { sub(/^.*\/\* *test: */, ""); sub(/ *\*\/.*$$/, ""); print }' $< > $@ + perl -- getcomments.pl -p='test:\s' -f='%' $< > $@ + $(call PASS, SUCCESS) + +test_%: %.test %.exe + IFS=$$'\n'; RC=0; \ + for test in `cat $< | sed 's,${<:.test=.exe},$(VALGRIND) ./${<:.test=.exe},g'`; do \ + echo "=== $$test ==="; \ + eval $$test; \ + [ $$? -eq 0 ] && echo -e "\033[1;32mSUCCESS\033[0;0m" \ + || { echo -e "\033[1;31mFAILED\033[0;0m"; RC=1; }; \ + done; \ + test "$$RC" -ne 1 + +valgrind_%: %.exe + VALGRIND="valgrind -v --leak-check=full --log-fd=3"; \ + export VALGRIND; \ + $(MAKE) $(@:valgrind_%=test_%) 3>$@.log + +%.d: %.c + $(call TITLE, "Building $@") + $(CC) $(INCLUDES) -MM $< -o $@~ + echo ${<:.c=.o}: $(shell perl -- getcomments.pl -p='depend:\s' -f='%' $<) >> $@~ + mv $@~ $@ + $(call PASS, SUCCESS) + +%.ld: %.c + $(call TITLE, "Building $@") + echo ${<:.c=.exe}: $(shell perl -- getcomments.pl -p='$(LDOPT):\s' -f='%' $< | awk '{for (i=1;i<=NF;i++) if ($$(i) ~ /.o$$/) printf " %s", $$(i)}') > $@ + $(call PASS, SUCCESS) + +%.o: %.c + $(call TITLE, "Building $@") + $(CC) $(CFLAGS) $(INCLUDES) $(shell perl -- getcomments.pl -p='cflags:\s' -f='%' $<) -c $< -o $@ + $(call PASS, SUCCESS) + + +%.exe: %.o %.d + $(call TITLE, "Building $@") + $(CC) $(LDFLAGS) $< $(shell perl -- getcomments.pl -p='$(LDOPT):\s' -f='%' ${<:.o=.c}) $(LDLIBS) -o $@ + $(call PASS, SUCCESS) + +## Phony + +.PHONY: all clean count depends gcovs purge tests + +## Precious + +.PRECIOUS: %.d %.o diff --git a/scrabble.c b/scrabble.c new file mode 100644 index 0000000..26b6d19 --- /dev/null +++ b/scrabble.c @@ -0,0 +1,117 @@ +/* depend: */ +/* cflags: */ +/* linker: board.o debug.o -lcurses */ +/* winlnk: board.o debug.o -lpdcurses */ + +#include +#include +#include + +#include "board.h" +#include "debug.h" + +/* static variables */ +char *progname = NULL; +char *version = "0.1"; + +char *language = "FR"; + +int usage (int ret) +{ + FILE *fd = ret ? stderr : stdout; + fprintf (fd, "usage: %s [-h] [-l lang] [-v level]\n", progname); + fprintf (fd, " -h: help message\n"); + fprintf (fd, " -l: language (%s)\n", language); + fprintf (fd, " -v: verbose level (%d)\n", verbose); + fprintf (fd, "%s version %s\n", progname, version); + + return ret; +} + +/* main function */ +int main (int argc, char *argv[]) +{ + + /* get basename */ + char *pt = progname = argv[0]; + while (*pt) { + if ((*pt == '/') || (*pt == '\\')) { + progname = pt + 1; + } + pt++; + } + + /* process argument */ + while (argc-- > 1) { + char *arg = *(++argv); + if (arg[0] != '-') { + VERBOSE (ERROR, fprintf (stderr, "%s: invalid option -- %s\n", progname, arg)); + return usage (1); + } + char c = arg[1]; + switch (c) { + case 'l': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg) { + language = arg; + } else { + VERBOSE (ERROR, fprintf (stderr, "%s: no language specified\n", progname)); + return usage (1); + } + break; + case 'v': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: missing verbose level\n", progname)); + return usage (1); + } + verbose = atoi (arg); + break; + case 'h': + default: + return usage (c != 'h'); + } + } + + initscr(); + //seed = time((time_t *)0); + //srand(seed); + + noecho(); + cbreak(); + nonl(); + + start_color (); + //endwin (); + + char *tab = initboard (); + + int c = 0; + int stop = 0, mode = 0; + while (!stop) { + showboard (tab, 4, 4, mode); + + c = getch (); + switch (c) { + case 'q': + stop = 1; + break; + case ERR: + break; + default: + mode = mode^1; + } + } + + endwin (); + + return 0; +} + +/* test: scrabble.exe -l 2>&1 | grep error */ +/* test: scrabble.exe -h | grep usage */ +/* test: scrabble.exe -v 2>&1 | grep missing */ +/* test: scrabble.exe -s 2>&1 | grep missing */ +/* test: scrabble.exe _ 2>&1 | grep invalid */ + +/* vim: set ts=4 sw=4 et: */