Re-added the option to use vt100 escape codes
This commit is contained in:
parent
a2142a48b5
commit
2b27aef099
7 changed files with 244 additions and 26 deletions
14
config.h
14
config.h
|
|
@ -8,17 +8,3 @@
|
||||||
|
|
||||||
#define ONLYPUT
|
#define ONLYPUT
|
||||||
#define ARROWS
|
#define ARROWS
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,13 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "logic.h"
|
#include "macros.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "logic.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
#define VERSION 0.0.1
|
#define VERSION 0.0.2
|
||||||
|
|
||||||
#define XSTR(s) STR(s)
|
|
||||||
#define STR(s) #s
|
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
// First the boilerplate stuffs
|
// First the boilerplate stuffs
|
||||||
|
|
|
||||||
5
macros.h
Normal file
5
macros.h
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define XSTR(s) STR(s)
|
||||||
|
#define STR(s) #s
|
||||||
16
makefile
16
makefile
|
|
@ -10,10 +10,13 @@ OUTDIR = out
|
||||||
|
|
||||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
|
OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
|
#UI_TARGET = vt100
|
||||||
UI_TARGET = ncurses
|
UI_TARGET = ncurses
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
|
|
||||||
|
.NOTINTERMEDIATE:
|
||||||
|
|
||||||
MSG_LINKING = Linking:
|
MSG_LINKING = Linking:
|
||||||
MSG_COMPILING = Compiling C:
|
MSG_COMPILING = Compiling C:
|
||||||
MSG_CLEANING = Cleaning:
|
MSG_CLEANING = Cleaning:
|
||||||
|
|
@ -22,18 +25,19 @@ MSG_CLEANING_OUT = Cleaning $(OUTDIR):
|
||||||
|
|
||||||
all: $(OUTDIR)/connect4_$(UI_TARGET).elf
|
all: $(OUTDIR)/connect4_$(UI_TARGET).elf
|
||||||
|
|
||||||
clean_run: clean run
|
|
||||||
|
|
||||||
run: $(OUTDIR)/connect4_$(UI_TARGET).elf
|
run: $(OUTDIR)/connect4_$(UI_TARGET).elf
|
||||||
./$<
|
./$<
|
||||||
|
|
||||||
$(OUTDIR)/connect4_ncurses.elf: $(OBJDIR)/ui_ncurses.o $(OBJDIR)/logic.o $(OBJDIR)/connect4.o
|
run_%: $(OUTDIR)/connect4_%.elf
|
||||||
|
./$<
|
||||||
|
|
||||||
|
$(OUTDIR)/connect4_ncurses.elf: $(addprefix $(OBJDIR)/,ui_ncurses.o logic.o connect4.o)
|
||||||
@echo
|
@echo
|
||||||
@echo $(MSG_LINKING) $@
|
@echo $(MSG_LINKING) $@
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
$(CC) $(FLAGS) -lncursesw -o $@ $^
|
$(CC) $(FLAGS) -lncursesw -o $@ $^
|
||||||
|
|
||||||
$(OUTDIR)/connect4_%.elf: $(OBJDIR)/ui_%.o $(OBJDIR)/logic.o $(OBJDIR)/connect4.o
|
$(OUTDIR)/connect4_%.elf: $(addprefix $(OBJDIR)/,ui_%.o logic.o connect4.o)
|
||||||
@echo
|
@echo
|
||||||
@echo $(MSG_LINKING) $@
|
@echo $(MSG_LINKING) $@
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
|
|
@ -49,6 +53,6 @@ clean:
|
||||||
@echo
|
@echo
|
||||||
@echo $(MSG_CLEANING)
|
@echo $(MSG_CLEANING)
|
||||||
@echo $(MSG_CLEANING_OBJ)
|
@echo $(MSG_CLEANING_OBJ)
|
||||||
rm $(OBJDIR)/*.o
|
rm -f $(OBJDIR)/*.o
|
||||||
@echo $(MSG_CLEANING_OUT)
|
@echo $(MSG_CLEANING_OUT)
|
||||||
rm $(OUTDIR)/*.elf
|
rm -f $(OUTDIR)/*.elf
|
||||||
|
|
|
||||||
1
types.h
1
types.h
|
|
@ -1,5 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
||||||
57
ui_ncurses.c
57
ui_ncurses.c
|
|
@ -20,6 +20,51 @@
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
|
#ifndef INPUT_X
|
||||||
|
#define INPUT_X 2
|
||||||
|
#endif
|
||||||
|
#ifndef INPUT_Y
|
||||||
|
#define INPUT_Y 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARROWS
|
||||||
|
|
||||||
|
#ifndef SCOREBOARD_X
|
||||||
|
#define SCOREBOARD_X 2
|
||||||
|
#endif
|
||||||
|
#ifndef SCOREBOARD_Y
|
||||||
|
#define SCOREBOARD_Y 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef SCOREBOARD_X
|
||||||
|
#define SCOREBOARD_X INPUT_X
|
||||||
|
#endif
|
||||||
|
#ifndef SCOREBOARD_Y
|
||||||
|
#define SCOREBOARD_Y INPUT_Y + 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOARD_X
|
||||||
|
#define BOARD_X SCOREBOARD_X + 28
|
||||||
|
#endif
|
||||||
|
#ifndef BOARD_Y
|
||||||
|
#define BOARD_Y SCOREBOARD_Y + 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOARD_DX
|
||||||
|
#define BOARD_DX 3
|
||||||
|
#endif
|
||||||
|
#ifndef BOARD_DY
|
||||||
|
#define BOARD_DY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SCOREBOARD_HEIGTH
|
||||||
|
#define SCOREBOARD_HEIGTH 10
|
||||||
|
#endif
|
||||||
|
|
||||||
void initBoard( void ){
|
void initBoard( void ){
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
initscr();
|
initscr();
|
||||||
|
|
@ -249,9 +294,19 @@ int askColumn(
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ONLYPUT
|
#ifndef ONLYPUT
|
||||||
static move_t askMove( void ){
|
move_t askMove( void ){
|
||||||
move_t move = PUT;
|
move_t move = PUT;
|
||||||
// TODO: actually ask what move
|
// TODO: actually ask what move
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
#endif /* ! ONLYPUT */
|
#endif /* ! ONLYPUT */
|
||||||
|
|
||||||
|
#undef INPUT_X
|
||||||
|
#undef INPUT_Y
|
||||||
|
#undef SCOREBOARD_X
|
||||||
|
#undef SCOREBOARD_Y
|
||||||
|
#undef BOARD_X
|
||||||
|
#undef BOARD_Y
|
||||||
|
#undef BOARD_DX
|
||||||
|
#undef BOARD_DY
|
||||||
|
#undef SCOREBOARD_HEIGTH
|
||||||
|
|
|
||||||
169
ui_vt100.c
Normal file
169
ui_vt100.c
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* AnnaConnect is a silly little text-based connect 4 game c:
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation, either version 2 of the License
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "ui.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
|
#define BOARD_WIDTH_CHARS ( 3 * BOARD_WIDTH + 6 )
|
||||||
|
#define SCOREBOARD_OFFSET 5
|
||||||
|
#define SCOREBOARD_WIDTH 27
|
||||||
|
#define SCOREBOARD_HEIGTH 9
|
||||||
|
|
||||||
|
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 ){
|
||||||
|
}
|
||||||
|
putchar( '\n' );
|
||||||
|
}
|
||||||
|
// 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' );
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBoard(
|
||||||
|
const wins_t wins,
|
||||||
|
const board_t board,
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
#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
|
||||||
|
);
|
||||||
|
printf( "\033[2K\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int askColumn(
|
||||||
|
const board_t board
|
||||||
|
#ifndef ONLYPUT
|
||||||
|
,const move_t move
|
||||||
|
#endif /* ONLYPUT */
|
||||||
|
){
|
||||||
|
int column;
|
||||||
|
for(;;){
|
||||||
|
#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 );
|
||||||
|
#endif /* ONLYPUT */
|
||||||
|
printf( "\033[K" ); // clear everything after cursor
|
||||||
|
scanf( "%d", &column );
|
||||||
|
column -= FIRST_NUMBER;
|
||||||
|
if( column >= 0 && column < BOARD_WIDTH )
|
||||||
|
#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" );
|
||||||
|
#ifndef ONLYPUT
|
||||||
|
break;
|
||||||
|
case POP:
|
||||||
|
if( board.heigth [ column ] != 0 )
|
||||||
|
return column;
|
||||||
|
else printf( "\033[2Apls enter a column that ain't empty" );
|
||||||
|
}
|
||||||
|
#endif /* ! ONLYPUT */
|
||||||
|
else
|
||||||
|
printf( "\033[2Apls enter valid column" );
|
||||||
|
printf( "\033[K\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ONLYPUT
|
||||||
|
move_t askMove( void ){
|
||||||
|
move_t move = PUT;
|
||||||
|
// TODO: actually ask what move
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
#endif /* ! ONLYPUT */
|
||||||
|
|
||||||
|
#undef BOARD_WIDTH_CHARS
|
||||||
|
#undef SCOREBOARD_OFFSET
|
||||||
|
#undef SCOREBOARD_WIDTH
|
||||||
|
#undef SCOREBOARD_HEIGTH
|
||||||
Loading…
Add table
Add a link
Reference in a new issue