From a561d5b61c6c6f6cb1a4a403c96ed6dc03c0525c Mon Sep 17 00:00:00 2001 From: AnnaSnoeijs Date: Fri, 6 Jun 2025 21:31:59 +0200 Subject: [PATCH] Rewrote alot of shtuff to trans the code to ncurses instead of using VT100 escape codes directly --- connect4.c | 295 ++++++++++++++++++++++++++++++++--------------------- makefile | 2 +- 2 files changed, 182 insertions(+), 115 deletions(-) diff --git a/connect4.c b/connect4.c index 22c90fc..e2dea63 100644 --- a/connect4.c +++ b/connect4.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * AnnaConnect is a silly little text-based connect 4 game c: - * Copyright (C) 2024 Anna Snoeijs. anna@snoeijs.tech + * Copyright (C) 2025 Anna Snoeijs. anna@snoeijs.tech * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,14 +16,32 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #include +#include +#include +#include + +#define VERSION 25.01.sid #define BOARD_WIDTH 7 #define BOARD_HEIGTH 6 #define FIRST_NUMBER 1 +#define INPUT_X 2 +#define INPUT_Y 1 + +#define SCOREBOARD_X INPUT_X +#define SCOREBOARD_Y INPUT_Y + 2 + +#define BOARD_X SCOREBOARD_X + 28 +#define BOARD_Y SCOREBOARD_Y + 1 + +#define BOARD_DX 3 +#define BOARD_DY 1 + +#define SCOREBOARD_HEIGTH 10 + #define XSTR(s) STR(s) #define STR(s) #s @@ -89,104 +107,144 @@ static inline int bottomHeigthMask( const int a, const int b ){ return safeHeigthMask( bottom( a, b ) ); } -#define BOARD_WIDTH_CHARS ( 3 * BOARD_WIDTH + 6 ) -#define SCOREBOARD_OFFSET 5 -#define SCOREBOARD_WIDTH 27 -#define SCOREBOARD_HEIGTH 9 static void initBoard( void ){ - for(int i = SCOREBOARD_HEIGTH - ( BOARD_HEIGTH + 2 ); i > 0; i-- ) - putchar( '\n' ); - printf( "\n " ); - for( int column = 0; column < BOARD_WIDTH; column++ ) - printf( "%2d ", column + FIRST_NUMBER ); - putchar( '\n' ); - for( int row = BOARD_HEIGTH - 1; row > -1; row-- ){ - // begin row - printf( "%2d " , row + FIRST_NUMBER ); - for( int column = 0; column < BOARD_WIDTH; column++ ) - printf( "[ ]" ); - // end of row - printf( "%2d" , row + FIRST_NUMBER ); - switch( row ){ + setlocale(LC_ALL, ""); + initscr(); + keypad(stdscr, TRUE); + nonl(); + echo(); + for( int column = 0; column < BOARD_WIDTH; column++ ){ + char colnum[4]; + sprintf( colnum, "%2d", column + FIRST_NUMBER ); + mvaddstr( + BOARD_Y, + BOARD_X + BOARD_DX * ( column + 1 ), + colnum + ); + for(int row = 0; row < BOARD_HEIGTH; row++){ + mvaddstr( + BOARD_Y + BOARD_DY * ( row + 1 ), + BOARD_X + BOARD_DX * ( column + 1 ), + "[ ]" + ); } - putchar( '\n' ); + mvaddstr( + BOARD_Y + BOARD_DY * ( BOARD_HEIGTH + 1 ), + BOARD_X + BOARD_DX * ( column + 1 ), + colnum + ); + } + for(int row = 0; row < BOARD_HEIGTH; row++ ){ + char rownum[4]; + sprintf( rownum, "%2d", row + FIRST_NUMBER ); + mvaddstr( + BOARD_Y + BOARD_DY * ( row + 1 ), + BOARD_X, + rownum + ); + mvaddstr( + BOARD_Y + BOARD_DY * ( row + 1 ), + BOARD_X + BOARD_DX * ( BOARD_WIDTH + 1 ), + rownum + ); + } + for( int y = 0; y < SCOREBOARD_HEIGTH; y++ ){ + char *str; + switch(y){ + case 0: str = "┌───────────────┬────┬────┐"; break; + case 1: str = "│ player │ 0 │ 1 │"; break; + case 2: str = "├───────────────┼────┼────┤"; break; + case 3: str = "│ vertical │ │ │"; break; + case 4: str = "│ horizontal │ │ │"; break; + case 5: str = "│ diagonal up │ │ │"; break; + case 6: str = "│ diagonal down │ │ │"; break; + case 7: str = "├───────────────┼────┼────┤"; break; + case 8: str = "│ total │ │ │"; break; + case 9: str = "└───────────────┴────┴────┘"; break; + default: str = "The code be brokeys at initboard for the score"; + } + mvaddstr( + SCOREBOARD_Y + y, + SCOREBOARD_X, + str + ); } - // end of board - printf( " " ); - for( int column = 0; column < BOARD_WIDTH; column++ ) - printf( "%2d ", column + FIRST_NUMBER ); -#define SCOREBOARD_LINE_END "\033[B\033["XSTR(SCOREBOARD_WIDTH)"D" - printf("\033["XSTR(SCOREBOARD_OFFSET)"C\033["XSTR(SCOREBOARD_HEIGTH)"A" - "┌───────────────┬────┬────┐"SCOREBOARD_LINE_END - "│ player │ 0 │ 1 │"SCOREBOARD_LINE_END - "├───────────────┼────┼────┤"SCOREBOARD_LINE_END - "│ vertical │ │ │"SCOREBOARD_LINE_END - "│ horizontal │ │ │"SCOREBOARD_LINE_END - "│ diagonal up │ │ │"SCOREBOARD_LINE_END - "│ diagonal down │ │ │"SCOREBOARD_LINE_END - "├───────────────┼────┼────┤"SCOREBOARD_LINE_END - "│ total │ │ │"SCOREBOARD_LINE_END - "└───────────────┴────┴────┘"SCOREBOARD_LINE_END - ); -#undef SCOREBOARD_LINE_END - putchar( '\n' ); - putchar( '\n' ); } static void updateBoard( const wins_t wins, const board_t board, -#ifndef ONLYPUT - const move_t move, -#endif /* ! ONLYPUT */ const int column ){ - int heigth = board.heigth [ column ]; -#ifndef ONLYPUT - switch( move ){ - case PUT: // Only print the put one -#endif /* ! ONLYPUT */ - printf( - "\033[%dA\033[%dC%c\033[%dB", - heigth + 3, - column * 3 + 4, - '0' + !!( board.player ), - heigth + 1 - ); -#ifndef ONLYPUT - break; - default: // Print all the pieces in the column and the air above - printf( "\033[%dA", heigth + 4 ); - if( heigth < BOARD_HEIGTH ) printf( "\033[%dC ", column * 3 + 4 ); - else printf( "\033[%dC", column * 3 + 5 ); - for( int row = heigth; row --> 0; ) - printf( - "\033[B\033[D%c", - '0' + !!( board.column [ column ] & ( 1 << row ) ) - ); - printf( "\033[2B" ); + for(int row = 0; row < board.heigth[ column ]; row++){ + mvaddstr( + BOARD_Y + BOARD_DY * ( BOARD_HEIGTH - row ), + BOARD_X + 1 + BOARD_DX * ( column + 1 ), + board.column[ column ] & 1 << row ? "1" : "0" + ); } -#endif /* ! ONLYPUT */ - printf( - "\r\033[7A\033[%dC" - "%3d │%3d\033[B\033[8D" - "%3d │%3d\033[B\033[8D" - "%3d │%3d\033[B\033[8D" - "%3d │%3d\033[2B\033[8D" - "%3d │%3d\033[2B" - ,BOARD_WIDTH_CHARS + SCOREBOARD_WIDTH - 8 - ,wins.count0.vertical, wins.count1.vertical - ,wins.count0.horizontal, wins.count1.horizontal - ,wins.count0.diagonalUp, wins.count1.diagonalUp - ,wins.count0.diagonalDown, wins.count1.diagonalDown - ,wins.count0.total, wins.count1.total + char num[4]; + sprintf( num, "%3d", wins.count0.vertical ); + mvaddstr( + SCOREBOARD_Y + 3, + SCOREBOARD_X + 17, + num + ); + sprintf( num, "%3d", wins.count1.vertical ); + mvaddstr( + SCOREBOARD_Y + 3, + SCOREBOARD_X + 22, + num + ); + sprintf( num, "%3d", wins.count0.horizontal ); + mvaddstr( + SCOREBOARD_Y + 4, + SCOREBOARD_X + 17, + num + ); + sprintf( num, "%3d", wins.count1.horizontal ); + mvaddstr( + SCOREBOARD_Y + 4, + SCOREBOARD_X + 22, + num + ); + sprintf( num, "%3d", wins.count0.diagonalUp ); + mvaddstr( + SCOREBOARD_Y + 5, + SCOREBOARD_X + 17, + num + ); + sprintf( num, "%3d", wins.count1.diagonalUp ); + mvaddstr( + SCOREBOARD_Y + 5, + SCOREBOARD_X + 22, + num + ); + sprintf( num, "%3d", wins.count0.diagonalDown ); + mvaddstr( + SCOREBOARD_Y + 6, + SCOREBOARD_X + 17, + num + ); + sprintf( num, "%3d", wins.count1.diagonalDown ); + mvaddstr( + SCOREBOARD_Y + 6, + SCOREBOARD_X + 22, + num + ); + sprintf( num, "%3d", wins.count0.total ); + mvaddstr( + SCOREBOARD_Y + 8, + SCOREBOARD_X + 17, + num + ); + sprintf( num, "%3d", wins.count1.total ); + mvaddstr( + SCOREBOARD_Y + 8, + SCOREBOARD_X + 22, + num ); - printf( "\033[2K\n" ); } -#undef BOARD_WIDTH_CHARS -#undef SCOREBOARD_OFFSET -#undef SCOREBOARD_WIDTH -#undef SCOREBOARD_HEIGTH static void playMove( board_t *boardptr, @@ -217,39 +275,53 @@ static int askColumn( ,const move_t move #endif /* ONLYPUT */ ){ - int column; + int column = 0; for(;;){ + mvaddstr( + INPUT_Y, + INPUT_X, + "Where does player " + ); + if( board.player ) addstr( "1" ); + else addstr( "0" ); #ifndef ONLYPUT switch( move ){ - case PUT: printf( "Wher player %d put? ", board.player ); - break; - case POP: printf( "Wher player %d pop? ", board.player ); - } -#else /* ONLYPUT */ - printf( "Wher player %d put? ", board.player ); + case PUT: #endif /* ONLYPUT */ - printf( "\033[K" ); // clear everything after cursor - scanf( "%d", &column ); + addstr( " put the piece? " ); +#ifndef ONLYPUT + break; + case POP: + addstr( " pop a piece? " ); + } +#endif /* ONLYPUT */ + clrtoeol(); + refresh(); + scanw( " %d", &column ); column -= FIRST_NUMBER; - if( column >= 0 && column < BOARD_WIDTH ) + move( + INPUT_Y + 1, + INPUT_X + ); + clrtoeol(); + if( column >= 0 && column < BOARD_WIDTH ) // The collumn--; is a really + // temporary placeholder to make the unfinished shit compile at least #ifndef ONLYPUT switch( move ){ case PUT: #endif /* ! ONLYPUT */ if( board.heigth [ column ] < BOARD_HEIGTH ) return column; - else printf( "\033[2Apls enter a column that ain't full" ); + else addstr( "Pls enter a column that ain't full" ); #ifndef ONLYPUT break; case POP: if( board.heigth [ column ] != 0 ) return column; - else printf( "\033[2Apls enter a column that ain't empty" ); + else addstr( "Pls enter a column that ain't empty" ); } #endif /* ! ONLYPUT */ - else - printf( "\033[2Apls enter valid column" ); - printf( "\033[K\n" ); + else addstr( "Pls enter a column that exists" ); } } @@ -367,12 +439,13 @@ static void calcWins( int main(){ // First the boilerplate stuffs printf( - "AnnaConnect version 2024, Copyright (C) Anna Snoeijs\n" + "AnnaConnect version "XSTR(VERSION)", Copyright (C) Anna Snoeijs\n" "AnnaConnect comes with ABSOLUTELY NO WARRANTY\n" "This is free software, and you are welcome to redistribute it\n" "under certain condtions\n" ); // board, innit? + initBoard(); board_t playboard = { .player = 0, .column = {0}, @@ -396,22 +469,16 @@ int main(){ .win0 = {0}, .win1 = {0}, }; + for(;; playboard.player = !playboard.player ){ #ifndef ONLYPUT - move_t move = PUT; -#endif /* ! ONLYPUT */ - initBoard(); - for( int column = 0;; playboard.player = !playboard.player ){ -#ifndef ONLYPUT - move = askMove(); - column = askColumn( playboard, move ); + move_t move = askMove(); + int column = askColumn( playboard, move ); playMove( &playboard, move, column ); - calcWins( &wins, playboard ); - updateBoard( wins, playboard, move, column ); #else /* ONLYPUT */ - column = askColumn( playboard ); + int column = askColumn( playboard ); playMove( &playboard, column ); +#endif /* ONLYPUT */ calcWins( &wins, playboard ); updateBoard( wins, playboard, column ); -#endif /* ONLYPUT */ } } diff --git a/makefile b/makefile index 2c0c5d5..290e1a6 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ #!/usr/bin/make -f -FLAGS = -O3 -pedantic -Wall -Wextra -Werror +FLAGS = -O3 -pedantic -Wall -Wextra -Werror -lncursesw AnnaConnect: connect4.c cc $(FLAGS) -o connect4 connect4.c