initial commit

This commit is contained in:
Gregory Gauthier 2025-10-06 14:01:05 +01:00
commit cdd51fdf5c
18 changed files with 12742 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea/
cmake-build-debug/

13
CMakeLists.txt Normal file
View File

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 4.0)
project(cordle C)
set(CMAKE_C_STANDARD 90)
# Find the curses library
find_package(Curses REQUIRED)
add_executable(cordle cordle.c)
# Link against the curses library
target_link_libraries(cordle ${CURSES_LIBRARIES})
target_include_directories(cordle PRIVATE ${CURSES_INCLUDE_DIRS})

33
CordleDosBoxLauncher.bat Normal file
View File

@ -0,0 +1,33 @@
@echo off
REM DOSBox Launcher for Cordle
REM Automatically starts DOSBox with correct configuration
echo ================================================
echo Starting DOSBox for Cordle Development
echo ================================================
echo.
REM Check if DOSBox is installed
where dosbox >nul 2>&1
if %errorlevel% neq 0 (
echo ERROR: DOSBox not found in PATH
echo.
echo Please install DOSBox from: https://www.dosbox.com/
echo Or specify the full path to dosbox.exe below
pause
exit /b 1
)
REM Check if config file exists
if not exist "dosbox-cordle.conf" (
echo ERROR: dosbox-cordle.conf not found
echo Please ensure the config file is in the current directory
pause
exit /b 1
)
echo Launching DOSBox...
echo.
dosbox -conf dosbox-cordle.conf
pause

124
CordleDosMakefile.mk Normal file
View File

@ -0,0 +1,124 @@
# Makefile for Cordle - Cross-platform C90 Wordle Game
# Supports Unix/Linux/macOS and DOS (DJGPP)
#
# Usage:
# Unix/Linux/macOS: make
# DOS (DJGPP): make
# Clean: make clean
# Compiler
CC = gcc
# Compiler flags - strict C90 compliance
CFLAGS = -std=c90 -Wall -Wextra -pedantic -O2
# Source files
SRC = cordle.c
OBJ = cordle.o
# Platform detection and configuration
# Check for DOS/Windows environment
ifdef COMSPEC
# DOS/Windows detected
PLATFORM = DOS
TARGET = cordle.exe
CURSES_LIB = -lpdcurses
RM = del /Q
RMDIR = rmdir /S /Q
PATHSEP = \\
# DOS-specific flags
CFLAGS += -DMSDOS
else
ifdef ComSpec
# Alternative Windows detection
PLATFORM = DOS
TARGET = cordle.exe
CURSES_LIB = -lpdcurses
RM = del /Q
RMDIR = rmdir /S /Q
PATHSEP = \\
CFLAGS += -DMSDOS
else
# Unix/Linux/macOS
PLATFORM = UNIX
TARGET = cordle
CURSES_LIB = -lncurses
RM = rm -f
RMDIR = rm -rf
PATHSEP = /
endif
endif
# Additional libraries
LIBS = $(CURSES_LIB)
# Phony targets
.PHONY: all clean help info
# Default target
all: info $(TARGET)
# Display build information
info:
@echo ============================================
@echo Building Cordle for $(PLATFORM)
@echo Compiler: $(CC)
@echo Flags: $(CFLAGS)
@echo Libraries: $(LIBS)
@echo ============================================
@echo
# Build target
$(TARGET): $(SRC)
$(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(LIBS)
@echo
@echo ============================================
@echo Build complete: $(TARGET)
@echo ============================================
@echo
@echo To run: ./$(TARGET) --help
@echo
# Object file (alternative build method)
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -c $(SRC)
# Clean build artifacts
clean:
@echo Cleaning build artifacts...
$(RM) $(TARGET) $(OBJ)
@echo Clean complete.
# Help target
help:
@echo Cordle Makefile - Build Instructions
@echo =====================================
@echo
@echo Targets:
@echo make - Build the game
@echo make clean - Remove build artifacts
@echo make help - Show this help message
@echo make info - Show build configuration
@echo
@echo Platform Detection:
@echo Current: $(PLATFORM)
@echo
@echo DOS/DJGPP Requirements:
@echo - DJGPP compiler installed
@echo - PDCurses library installed
@echo - Make utility available
@echo
@echo Unix/Linux/macOS Requirements:
@echo - GCC compiler
@echo - ncurses library
@echo - Make utility
@echo
@echo Game Options:
@echo ./$(TARGET) --easy Easy difficulty
@echo ./$(TARGET) --medium Medium difficulty
@echo ./$(TARGET) --hard Hard difficulty
@echo ./$(TARGET) --techy Technical words
@echo ./$(TARGET) --literary Literary words
@echo ./$(TARGET) --cultural Cultural words
@echo ./$(TARGET) --full Full dictionary
@echo ./$(TARGET) --help Show game help

12
DosBoxCordleSetupGuide.md Normal file
View File

@ -0,0 +1,12 @@
# DOSBox Setup for Cordle Development
## Quick Start
### 1. Install DOSBox
**Windows:**
- Download from: https://www.dosbox.com/download.php?main=1
- Install using the installer
- Or use Chocolatey: `choco install dosbox`
**macOS:**

30
DosboxCordleLauncher.sh Normal file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# DOSBox Launcher for Cordle
# Automatically starts DOSBox with correct configuration
echo "================================================"
echo "Starting DOSBox for Cordle Development"
echo "================================================"
echo
# Check if DOSBox is installed
if ! command -v dosbox &> /dev/null; then
echo "ERROR: DOSBox not found"
echo
echo "Install DOSBox:"
echo " macOS: brew install dosbox"
echo " Linux: sudo apt-get install dosbox"
echo " or sudo yum install dosbox"
exit 1
fi
# Check if config file exists
if [ ! -f "dosbox-cordle.conf" ]; then
echo "ERROR: dosbox-cordle.conf not found"
echo "Please ensure the config file is in the current directory"
exit 1
fi
echo "Launching DOSBox..."
echo
dosbox -conf dosbox-cordle.conf

612
cordle.c Normal file
View File

@ -0,0 +1,612 @@
/* pyrdle.c - Pure C90 implementation of the Wordle-like game */
/* Compile with: gcc -std=c90 -o pyrdle pyrdle.c -lncurses */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <curses.h>
#include <ctype.h>
#define MAX_WORDS 10000
#define WORD_LENGTH 5
#define MAX_GUESSES 6
#define MAX_FILENAME 256
#define MAX_MESSAGE 256
/* Color pair constants */
#define COLOR_DEFAULT 1
#define COLOR_CORRECT 2 /* Green - correct position */
#define COLOR_PRESENT 3 /* Yellow - wrong position */
#define COLOR_ABSENT 4 /* Red - not in word */
#define COLOR_WWHITE 7 /* White text */
#define COLOR_UNUSED 6 /* Gray - unused letters */
/* Letter status constants */
#define STATUS_UNUSED 0
#define STATUS_ABSENT 1
#define STATUS_PRESENT 2
#define STATUS_CORRECT 3
/* Keyboard layout */
static const char* keyboard_rows[3] = {
"QWERTYUIOP",
"ASDFGHJKL",
"ZXCVBNM"
};
/* Game state structure */
typedef struct {
char words[MAX_WORDS][WORD_LENGTH + 1];
int word_count;
char target_word[WORD_LENGTH + 1];
char guesses[MAX_GUESSES][WORD_LENGTH + 1];
int guess_colors[MAX_GUESSES][WORD_LENGTH];
int guess_count;
char current_guess[WORD_LENGTH + 1];
int current_guess_length;
int game_over;
int won;
int letter_status[26]; /* A-Z status */
} GameState;
/* Function declarations */
int load_words(GameState* game, const char* filename);
int is_valid_word(GameState* game, const char* word);
void check_guess(GameState* game, const char* guess, int* colors);
int make_guess(GameState* game, const char* guess);
void draw_title(WINDOW* win, int y, const char* difficulty);
void draw_board(WINDOW* win, GameState* game, int y);
void draw_keyboard(WINDOW* win, GameState* game, int y);
void draw_message(WINDOW* win, const char* message, int y, int color_pair);
void draw_instructions(WINDOW* win, int y);
void parse_arguments(int argc, char* argv[], char* filename, char* difficulty);
void init_game(GameState* game);
void to_upper(char* str);
int main_game_loop(int argc, char* argv[]);
/* Initialize game state */
void init_game(GameState* game) {
int i, j;
game->word_count = 0;
game->target_word[0] = '\0';
game->guess_count = 0;
game->current_guess[0] = '\0';
game->current_guess_length = 0;
game->game_over = 0;
game->won = 0;
/* Initialize letter status to unused */
for (i = 0; i < 26; i++) {
game->letter_status[i] = STATUS_UNUSED;
}
/* Clear guesses */
for (i = 0; i < MAX_GUESSES; i++) {
game->guesses[i][0] = '\0';
for (j = 0; j < WORD_LENGTH; j++) {
game->guess_colors[i][j] = COLOR_DEFAULT;
}
}
}
/* Convert string to uppercase */
void to_upper(char* str) {
int i;
for (i = 0; str[i]; i++) {
str[i] = toupper(str[i]);
}
}
/* Load words from file */
int load_words(GameState* game, const char* filename) {
FILE* file;
char filepath[MAX_FILENAME];
char line[32];
char word[WORD_LENGTH + 1];
int len;
/* Construct file path */
sprintf(filepath, "wordlists/%s", filename);
file = fopen(filepath, "r");
if (!file) {
/* Try without wordlists/ prefix */
file = fopen(filename, "r");
if (!file) {
return 0;
}
}
game->word_count = 0;
while (fgets(line, sizeof(line), file) && game->word_count < MAX_WORDS) {
/* Remove newline and whitespace */
len = strlen(line);
while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r' || line[len-1] == ' ')) {
line[--len] = '\0';
}
if (len == WORD_LENGTH) {
strcpy(word, line);
to_upper(word);
strcpy(game->words[game->word_count], word);
game->word_count++;
}
}
fclose(file);
if (game->word_count == 0) {
return 0;
}
/* Select random target word */
srand((unsigned int)time(NULL));
strcpy(game->target_word, game->words[rand() % game->word_count]);
return 1;
}
/* Check if word exists in word list */
int is_valid_word(GameState* game, const char* word) {
int i;
char upper_word[WORD_LENGTH + 1];
strcpy(upper_word, word);
to_upper(upper_word);
for (i = 0; i < game->word_count; i++) {
if (strcmp(game->words[i], upper_word) == 0) {
return 1;
}
}
return 0;
}
/* Check guess against target word */
void check_guess(GameState* game, const char* guess, int* colors) {
char target_copy[WORD_LENGTH + 1];
char guess_copy[WORD_LENGTH + 1];
int i, j;
int target_used[WORD_LENGTH] = {0};
strcpy(target_copy, game->target_word);
strcpy(guess_copy, guess);
to_upper(guess_copy);
/* Initialize all as absent */
for (i = 0; i < WORD_LENGTH; i++) {
colors[i] = COLOR_ABSENT;
}
/* First pass: mark correct positions */
for (i = 0; i < WORD_LENGTH; i++) {
if (guess_copy[i] == target_copy[i]) {
colors[i] = COLOR_CORRECT;
target_used[i] = 1;
game->letter_status[guess_copy[i] - 'A'] = STATUS_CORRECT;
}
}
/* Second pass: mark present but wrong position */
for (i = 0; i < WORD_LENGTH; i++) {
if (colors[i] == COLOR_ABSENT) {
for (j = 0; j < WORD_LENGTH; j++) {
if (!target_used[j] && guess_copy[i] == target_copy[j]) {
colors[i] = COLOR_PRESENT;
target_used[j] = 1;
if (game->letter_status[guess_copy[i] - 'A'] != STATUS_CORRECT) {
game->letter_status[guess_copy[i] - 'A'] = STATUS_PRESENT;
}
break;
}
}
/* If still absent, mark letter as not in word */
if (colors[i] == COLOR_ABSENT) {
if (game->letter_status[guess_copy[i] - 'A'] == STATUS_UNUSED) {
game->letter_status[guess_copy[i] - 'A'] = STATUS_ABSENT;
}
}
}
}
}
/* Process a guess */
int make_guess(GameState* game, const char* guess) {
/* int i; */
char upper_guess[WORD_LENGTH + 1];
if (strlen(guess) != WORD_LENGTH) {
return 0;
}
if (!is_valid_word(game, guess)) {
return 0;
}
strcpy(upper_guess, guess);
to_upper(upper_guess);
strcpy(game->guesses[game->guess_count], upper_guess);
check_guess(game, guess, game->guess_colors[game->guess_count]);
game->guess_count++;
if (strcmp(upper_guess, game->target_word) == 0) {
game->game_over = 1;
game->won = 1;
} else if (game->guess_count >= MAX_GUESSES) {
game->game_over = 1;
game->won = 0;
}
return 1;
}
/* Draw game title */
void draw_title(WINDOW* win, int y, const char* difficulty) {
char title[256];
int height, width, x;
sprintf(title, "CORDLE - The C90 Wordle Game [%s]", difficulty);
getmaxyx(win, height, width);
x = (width - strlen(title)) / 2;
wattron(win, A_BOLD);
mvwaddstr(win, y, x, title);
wattroff(win, A_BOLD);
}
/* Draw the game board */
void draw_board(WINDOW* win, GameState* game, int y) {
int height, width, board_x;
int row, col, x_pos, y_pos;
char cell[4];
getmaxyx(win, height, width);
board_x = (width - (WORD_LENGTH * 4 - 1)) / 2;
for (row = 0; row < MAX_GUESSES; row++) {
y_pos = y + row * 2;
if (row < game->guess_count) {
/* Draw completed guess */
for (col = 0; col < WORD_LENGTH; col++) {
x_pos = board_x + col * 4;
sprintf(cell, "[%c]", game->guesses[row][col]);
wattron(win, COLOR_PAIR(game->guess_colors[row][col]));
mvwaddstr(win, y_pos, x_pos, cell);
wattroff(win, COLOR_PAIR(game->guess_colors[row][col]));
}
} else if (row == game->guess_count && !game->game_over) {
/* Draw current guess */
for (col = 0; col < WORD_LENGTH; col++) {
x_pos = board_x + col * 4;
if (col < game->current_guess_length) {
sprintf(cell, "[%c]", game->current_guess[col]);
} else {
strcpy(cell, "[ ]");
}
wattron(win, COLOR_PAIR(COLOR_WWHITE));
mvwaddstr(win, y_pos, x_pos, cell);
wattroff(win, COLOR_PAIR(COLOR_WWHITE));
}
} else {
/* Draw empty slots */
for (col = 0; col < WORD_LENGTH; col++) {
x_pos = board_x + col * 4;
mvwaddstr(win, y_pos, x_pos, "[ ]");
}
}
}
}
/* Draw visual keyboard */
void draw_keyboard(WINDOW* win, GameState* game, int y) {
int height, width;
int row_idx, x, y_pos, i;
const char* row;
char letter;
int status, color;
getmaxyx(win, height, width);
for (row_idx = 0; row_idx < 3; row_idx++) {
row = keyboard_rows[row_idx];
x = (width - strlen(row) * 2 + 1) / 2;
y_pos = y + row_idx;
/* Add indentation for keyboard layout */
if (row_idx == 1) x += 1;
else if (row_idx == 2) x += 3;
for (i = 0; row[i]; i++) {
letter = row[i];
status = game->letter_status[letter - 'A'];
switch (status) {
case STATUS_CORRECT: color = COLOR_CORRECT; break;
case STATUS_PRESENT: color = COLOR_PRESENT; break;
case STATUS_ABSENT: color = COLOR_ABSENT; break;
default: color = COLOR_UNUSED; break;
}
if (color == COLOR_UNUSED) {
wattron(win, A_DIM);
mvwaddch(win, y_pos, x, letter);
wattroff(win, A_DIM);
} else {
wattron(win, COLOR_PAIR(color));
mvwaddch(win, y_pos, x, letter);
wattroff(win, COLOR_PAIR(color));
}
x += 2;
}
}
}
/* Draw centered message */
void draw_message(WINDOW* win, const char* message, int y, int color_pair) {
int height, width, x;
getmaxyx(win, height, width);
x = (width - strlen(message)) / 2;
wattron(win, COLOR_PAIR(color_pair));
mvwaddstr(win, y, x, message);
wattroff(win, COLOR_PAIR(color_pair));
}
/* Draw game instructions */
void draw_instructions(WINDOW* win, int y) {
const char* instructions[] = {
"Guess the 5-letter word in 6 tries!",
"",
"Colors: GREEN=Correct, YELLOW=Wrong position, RED=Not in word",
"",
"Type letters: A-Z",
"Enter: Submit guess",
"Backspace: Delete letter",
"Ctrl+C or ESC: Quit game"
};
int num_instructions = 8;
int height, width, x, i;
getmaxyx(win, height, width);
for (i = 0; i < num_instructions; i++) {
if (y + i < height - 1) {
x = (width - strlen(instructions[i])) / 2;
mvwaddstr(win, y + i, x, instructions[i]);
}
}
}
/* Parse command line arguments */
void parse_arguments(const int argc, char* argv[], char* filename, char* difficulty) {
int i;
/* Default values */
strcpy(filename, "pyrdle_words_easy.txt");
strcpy(difficulty, "EASY");
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--easy") == 0) {
strcpy(filename, "pyrdle_words_easy.txt");
strcpy(difficulty, "EASY");
} else if (strcmp(argv[i], "--medium") == 0) {
strcpy(filename, "pyrdle_words_medium.txt");
strcpy(difficulty, "MEDIUM");
} else if (strcmp(argv[i], "--hard") == 0) {
strcpy(filename, "pyrdle_words_hard.txt");
strcpy(difficulty, "HARD");
} else if (strcmp(argv[i], "--techy") == 0) {
strcpy(filename, "pyrdle_words_techy.txt");
strcpy(difficulty, "TECHNICAL");
} else if (strcmp(argv[i], "--literary") == 0) {
strcpy(filename, "pyrdle_words_literary.txt");
strcpy(difficulty, "LITERARY");
} else if (strcmp(argv[i], "--cultural") == 0) {
strcpy(filename, "pyrdle_words_cultural.txt");
strcpy(difficulty, "CULTURAL");
} else if (strcmp(argv[i], "--full") == 0) {
strcpy(filename, "pyrdle_words_full.txt");
strcpy(difficulty, "FULL");
} else if (strcmp(argv[i], "--wordlist") == 0 && i + 1 < argc) {
strcpy(filename, argv[i + 1]);
strcpy(difficulty, "CUSTOM");
i++; /* Skip next argument */
}
}
}
/* Main game loop */
int main_game_loop(int argc, char* argv[]) {
WINDOW* stdscr;
GameState game;
char filename[MAX_FILENAME];
char difficulty[32];
char message[MAX_MESSAGE] = "";
int message_color = COLOR_DEFAULT;
int height, width, y_pos;
int key;
char temp_guess[WORD_LENGTH + 1];
char win_message[MAX_MESSAGE];
/* Get command line arguments */
parse_arguments(argc, argv, filename, difficulty);
/* Initialize ncurses */
stdscr = initscr();
curs_set(0); /* Hide cursor */
clear();
/* Initialize colors */
start_color();
init_pair(COLOR_DEFAULT, COLOR_WWHITE, COLOR_BLACK);
init_pair(COLOR_CORRECT, COLOR_BLACK, COLOR_GREEN);
init_pair(COLOR_PRESENT, COLOR_BLACK, COLOR_YELLOW);
init_pair(COLOR_ABSENT, COLOR_WWHITE, COLOR_RED);
init_pair(COLOR_WWHITE, COLOR_WWHITE, COLOR_BLACK);
init_pair(COLOR_UNUSED, COLOR_WWHITE, COLOR_BLACK);
/* Initialize game */
init_game(&game);
if (!load_words(&game, filename)) {
/* Try fallback */
if (strcmp(filename, "pyrdle_words.txt") != 0 &&
load_words(&game, "pyrdle_words.txt")) {
strcpy(difficulty, "DEFAULT");
} else {
mvaddstr(0, 0, "Error: Could not load word list");
mvaddstr(1, 0, "Press any key to exit...");
getch();
endwin();
return 1;
}
}
/* Main game loop */
while (1) {
clear();
getmaxyx(stdscr, height, width);
y_pos = 1;
/* Draw components */
draw_title(stdscr, y_pos, difficulty);
y_pos += 2;
draw_board(stdscr, &game, y_pos);
y_pos += MAX_GUESSES * 2 + 1;
draw_keyboard(stdscr, &game, y_pos);
y_pos += 4;
/* Draw message if exists */
if (strlen(message) > 0) {
draw_message(stdscr, message, y_pos, message_color);
y_pos += 2;
}
/* Draw instructions */
if (y_pos + 6 < height) {
draw_instructions(stdscr, y_pos);
}
/* Handle game over */
if (game.game_over) {
y_pos = (height > 20) ? height - 3 : y_pos;
if (game.won) {
sprintf(win_message, "Congratulations! You won in %d guesses!",
game.guess_count);
draw_message(stdscr, win_message, y_pos, COLOR_CORRECT);
} else {
sprintf(win_message, "Game Over! The word was: %s",
game.target_word);
draw_message(stdscr, win_message, y_pos, COLOR_ABSENT);
}
draw_message(stdscr, "Press 'N' for new game or 'Q' to quit",
y_pos + 1, COLOR_DEFAULT);
refresh();
key = getch();
if (key == 'n' || key == 'N') {
/* Start new game */
init_game(&game);
load_words(&game, filename);
strcpy(message, "");
continue;
} else if (key == 'q' || key == 'Q' || key == 27) {
break;
}
continue;
}
refresh();
/* Get input */
key = getch();
/* Handle input */
if (key == 27) { /* ESC */
break;
} else if (key == '\n' || key == '\r' || key == KEY_ENTER) {
if (game.current_guess_length == WORD_LENGTH) {
strcpy(temp_guess, game.current_guess);
if (make_guess(&game, temp_guess)) {
game.current_guess[0] = '\0';
game.current_guess_length = 0;
strcpy(message, "");
} else {
strcpy(message, "Not in word list!");
message_color = COLOR_ABSENT;
}
} else {
sprintf(message, "Word must be %d letters!", WORD_LENGTH);
message_color = COLOR_ABSENT;
}
} else if (key == KEY_BACKSPACE || key == 127 || key == '\b') {
if (game.current_guess_length > 0) {
game.current_guess_length--;
game.current_guess[game.current_guess_length] = '\0';
strcpy(message, "");
}
} else if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) {
if (game.current_guess_length < WORD_LENGTH) {
game.current_guess[game.current_guess_length] = toupper(key);
game.current_guess_length++;
game.current_guess[game.current_guess_length] = '\0';
strcpy(message, "");
}
}
}
endwin();
return 0;
}
/* Global variables for argc/argv (C90 limitation) */
static int __argc;
static char** __argv;
int main(int argc, char* argv[]) {
int i;
/* Store argc/argv globally for use in game loop */
__argc = argc;
__argv = argv;
/* Handle help */
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
printf("pyrdle - C90 Wordle Game\n\n");
printf("Usage: %s [OPTIONS]\n\n", argv[0]);
printf("Difficulty Levels:\n");
printf(" --easy Common everyday words (default)\n");
printf(" --medium Standard vocabulary\n");
printf(" --hard Challenging words\n\n");
printf("Word Categories:\n");
printf(" --techy Technical and scientific terms\n");
printf(" --literary Literary and archaic terms\n");
printf(" --cultural Cultural and international terms\n");
printf(" --full Complete dictionary\n\n");
printf("Custom:\n");
printf(" --wordlist FILE Use custom word list\n\n");
printf("Examples:\n");
printf(" %s --easy\n", argv[0]);
printf(" %s --techy\n", argv[0]);
printf(" %s --wordlist mywords.txt\n", argv[0]);
return 0;
}
}
return main_game_loop(argc, argv);
}

129
cordle_dos_REAMDE.txt Normal file
View File

@ -0,0 +1,129 @@
================================================================================
CORDLE - DOS BUILD INSTRUCTIONS
================================================================================
Building Cordle on DOS requires DJGPP (DJ Delorie's GCC Port) and PDCurses.
================================================================================
1. INSTALL DJGPP
================================================================================
Download and install DJGPP from: http://www.delorie.com/djgpp/
Required packages:
- djdev205.zip (DJGPP development kit)
- gcc930b.zip (GNU C Compiler)
- bnu234b.zip (GNU Binutils)
- mak43b.zip (GNU Make)
- fil41b.zip (GNU File utilities)
Unzip all packages to C:\DJGPP
Set environment variables in AUTOEXEC.BAT:
SET DJGPP=C:\DJGPP\DJGPP.ENV
SET PATH=C:\DJGPP\BIN;%PATH%
================================================================================
2. INSTALL PDCURSES
================================================================================
Download PDCurses from: https://pdcurses.org/
Build PDCurses for DOS:
cd pdcurses\dos
make -f Makefile.dj
Copy files:
copy pdcurses.a C:\DJGPP\LIB\libpdcurses.a
copy curses.h C:\DJGPP\INCLUDE\
copy panel.h C:\DJGPP\INCLUDE\
================================================================================
3. BUILD CORDLE
================================================================================
Copy the Cordle source files to your DOS system:
- cordle.c
- Makefile
- wordlists\ directory (with all word list files)
Build the game:
cd \CORDLE
make
This will create CORDLE.EXE
================================================================================
4. RUN THE GAME
================================================================================
Run with default settings:
cordle
Run with specific difficulty:
cordle --easy
cordle --medium
cordle --hard
Show help:
cordle --help
================================================================================
5. MEMORY REQUIREMENTS
================================================================================
Minimum:
- 2 MB RAM
- VGA compatible display (for colors)
- DOS 5.0 or higher
Recommended:
- 4 MB RAM
- 80x25 text mode or larger
================================================================================
6. TROUBLESHOOTING
================================================================================
Error: "Out of memory"
- Increase DOS memory limit
- Try using CWSDPMI.EXE memory extender
Error: "libpdcurses.a not found"
- Ensure PDCurses is properly installed
- Check library path: C:\DJGPP\LIB\
Error: "curses.h not found"
- Copy curses.h to C:\DJGPP\INCLUDE\
Colors not working:
- Ensure display supports VGA colors
- Try different terminal emulator
================================================================================
7. TESTING
================================================================================
Tested on:
- MS-DOS 6.22
- FreeDOS 1.3
- DOSBox (with DJGPP)
- DOSBox-X
================================================================================
8. FILE STRUCTURE
================================================================================
Required files:
CORDLE.EXE Main executable
WORDLISTS\ Word list directory
PYRDLE_WORDS_EASY.TXT
PYRDLE_WORDS_MEDIUM.TXT
PYRDLE_WORDS_HARD.TXT
(... other word lists ...)
================================================================================
For modern systems, use CMake build instead (see README.md)
================================================================================

117
dosbox_config_cordle.ini Normal file
View File

@ -0,0 +1,117 @@
# DOSBox Configuration File for Cordle
# =====================================
# This configuration is optimized for running and developing Cordle
#
# Usage: dosbox -conf dosbox-cordle.conf
[sdl]
# Display settings
fullscreen=false
fulldouble=false
fullresolution=original
windowresolution=original
output=opengl
autolock=true
[dosbox]
# DOSBox machine settings
machine=svga_s3
captures=capture
memsize=16
[render]
# Rendering and aspect ratio
frameskip=0
aspect=true
scaler=normal2x
[cpu]
# CPU settings - adjust if game runs too fast/slow
core=auto
cputype=auto
cycles=max
cycleup=10
cycledown=20
[mixer]
# Sound settings (not used by Cordle, but included for completeness)
nosound=false
rate=44100
blocksize=1024
prebuffer=25
[midi]
mpu401=intelligent
mididevice=default
midiconfig=
[sblaster]
sbtype=sb16
sbbase=220
irq=7
dma=1
hdma=5
sbmixer=true
oplmode=auto
oplemu=default
oplrate=44100
[gus]
gus=false
[speaker]
pcspeaker=true
pcrate=44100
tandy=auto
tandyrate=44100
disney=true
[joystick]
joysticktype=auto
[serial]
serial1=dummy
serial2=dummy
serial3=disabled
serial4=disabled
[dos]
# DOS settings
xms=true
ems=true
umb=true
keyboardlayout=auto
[ipx]
ipx=false
[autoexec]
# Auto-execute commands on DOSBox startup
@echo off
echo.
echo ===============================================
echo DOSBOX CONFIGURED FOR CORDLE DEVELOPMENT
echo ===============================================
echo.
# Mount the Cordle directory
# CHANGE THIS PATH TO YOUR ACTUAL CORDLE DIRECTORY
mount c: .
c:
# Set DJGPP environment if needed
# Uncomment and adjust paths if DJGPP is installed
# SET DJGPP=C:\DJGPP\DJGPP.ENV
# SET PATH=C:\DJGPP\BIN;%PATH%
echo Current directory mounted as C:
echo.
echo Available commands:
echo dir - List files
echo cd cordle - Change to cordle directory
echo make - Build the game
echo cordle --help - Show game help
echo cordle --easy - Play easy mode
echo exit - Exit DOSBox
echo.
echo ===============================================

View File

@ -0,0 +1,86 @@
# DOSBox-X Configuration for Cordle
# ==================================
# DOSBox-X provides better DOS compatibility and development features
# Download from: https://dosbox-x.com/
[sdl]
fullscreen=false
fulldouble=false
fullresolution=0x0
windowresolution=1024x768
output=opengl
autolock=true
sensitivity=100
waitonerror=true
priority=higher,normal
mapperfile=mapper-cordle.map
usescancodes=true
[dosbox]
language=
machine=svga_s3
captures=capture
memsize=32
startup_verbosity=high
[render]
frameskip=0
aspect=true
scaler=normal3x
glshader=default
[cpu]
core=auto
cputype=pentium_slow
cycles=max
cycleup=10
cycledown=20
[mixer]
nosound=false
rate=44100
blocksize=1024
prebuffer=25
[midi]
mpu401=intelligent
mididevice=default
[dos]
xms=true
ems=true
umb=true
ver=7.1
keyboardlayout=auto
[files]
nocachedir=false
[autoexec]
@echo off
cls
echo.
echo ===============================================
echo CORDLE - DOS DEVELOPMENT ENVIRONMENT
echo (DOSBox-X Enhanced)
echo ===============================================
echo.
# Mount current directory
mount c: .
c:
# Enhanced prompt
prompt $P$G
# Display useful info
echo DOSBox-X Version with enhanced DOS support
echo Memory: 32 MB configured
echo Display: SVGA S3 emulation
echo.
echo Quick Start:
echo make Build Cordle
echo cordle.exe Run the game
echo edit cordle.c Edit source (if edit is available)
echo.
echo ===============================================

2771
wordlists/pyrdle_words.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,247 @@
ADOBE
ALOHA
ALTAR
AMIGO
AMISH
AORTA
ATOLL
BABEL
BAGEL
BAYOU
BIMBO
BINGO
BIOME
BISON
BLITZ
BONGO
BORAX
BRAVO
BREWS
BRIGS
BRINY
BUDGE
BUGLE
BULKS
BUNKS
BURRO
CACTI
CALMS
CALYX
CAMEL
CAMEO
CANAL
CANDY
CANOE
CANON
CANTO
CAPED
CAPER
CAPON
CARNY
CAROL
CARPS
CASTE
CAULK
CAVED
CAVER
CAVES
CAVIL
CEASE
CEDAR
CEDED
CELEB
CELLO
CENTS
CHAFE
CHAFF
CHAMP
CHANT
CHAOS
CHAPS
CHARD
CHARM
CHARS
CHARY
CHASM
CHATS
CHEAP
CHEAT
CHECK
CHEEK
CHEEP
CHEER
CHESS
CHEST
CHEWY
CHICK
CHIDE
CHIEF
CHILD
CHILE
CHILI
CHILL
CHIME
CHIMP
CHINA
CHINK
CHINO
CHIPS
CHIRP
CHIVE
CHOCK
CHOIR
CHOKE
CHOMP
CHOPS
CHORD
CHORE
CHOSE
CHOWS
CHUCK
CHUMP
CHUNK
CHURN
CHUTE
CIDER
CIGAR
CINCH
CIRCA
CISCO
CITED
CITES
CIVET
CIVIC
CIVIL
CLACK
CLAIM
CLAMP
CLAMS
CLANG
CLANK
CLAPS
CLASH
CLASP
CLASS
CLAWS
CLAYS
CLEAN
CLEAR
CLEAT
CLEFT
CLERK
CLICK
CLIFF
CLIMB
CLIME
CLING
CLINK
CLOAK
CLOCK
CLONE
CLOPS
CLOSE
CLOTH
CLOTS
CLOUD
CLOUT
CLOVE
CLOWN
CLUBS
CLUCK
CLUED
CLUES
CLUMP
CLUNG
CLUNK
COACH
COALS
COAST
COATS
COBRA
COCKY
COCOA
CODED
CODER
CODES
CODEX
CODON
COEDS
COILS
COINS
COKES
COLDS
COLON
COLOR
COLTS
COMBO
COMBS
COMER
COMES
COMET
COMFY
COMIC
COMMA
CONCH
CONDO
CONED
CONES
CONEY
CONGA
CONGO
CONKS
COOED
COOKS
COOLS
COOPS
COOPT
COPED
COPER
COPES
COPSE
CORAL
CORDS
CORED
CORER
CORES
CORGI
CORKS
CORKY
CORNY
CORPS
COSTS
COUCH
COUGH
COULD
COUPE
COUPS
COURT
COUTH
COVEN
COVER
COVES
COVET
COWED
COWER
COYLY
COZEN
CRABS
CRACK
CRAFT
CRAGS
DHOTI
DINGO
DIRGE
DODOS
DOGMA
DOILY
DONNA
DONOR
DONUT
DOOMS
DOOZY
DOPED
DOPER
DOPES
DOPEY
DORKS
DORKY

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
ADAGE
AGLOW
ALOFT
APACE
ARDOR
ASKEW
ASPEN
ATONE
AUGUR
AVIAN
AVION
AWASH
BALMY
BEGOT
BELIE
BERTH
BESET
BESOT
BIDED
BILGE
BOWER
BRACE
BRIAR
BRINE
BRINY
CAIRN
CHIDE
CLEFT
COUTH
CRAVE
CREST
DALLY
DEWED
DIRGE
DOTED
DOWER
DREAR
DUSKY
DWELT
EAVES
EBBED
EDIFY
ELEGY
EMBER
ENSUE
EPOCH
ERRED
ESTOP
ETUDE
EVADE
EXALT
EXULT
FABLE
FEIGN
FEINT
FERAL
FETID
FJORD
FLESH
FLORA
FOLLY
FORGE
FORTE
FOUNT
FRIAR
FROST
FROTH
GABLE
GAILY
GAVEL
GLADE
GLEAN
GLOAM
GNARL
GNASH
GNOME
GORGE
GOUGE
GRAVE
GREBE
GRIEF
GRIFT
GRIME
GROVE
GUILD
GUILE
GULCH
GULLY
GUSTS
GUSTY
HAPLY
HARDY
HASTE
HAUNT
HAVEN
HEADY
HEATH
HEDGE
HEIGH
HENCE
HERON
HOARD
HOARY
HOIST
HOLLY
HORDE
HOUND
HOVEL
HOVER
IDYLL
INANE
INLET
LEDGE
LOFTY
MELEE
OCEAN
ONSET
OUGHT
PERCH
PIOUS
PLAIN
PLUMB
PRIDE
PRIME
PRIVY
PROUD
PROVE
PSALM
QUEST
QUEUE
QUITE
RAPID
REALM
REBEL
REIGN
RIDGE
RIVAL
ROOST
ROUGE
ROUTE
ROVER
RUDDY
RUMOR
SALLY
SCALE
SCORN
SEVER
SHADE
SHARD
SHAWL
SHEAR
SHEEN
SHIED
SHIRE
SHONE
SHORN
SHOVE
SHOWN
SHREW
SHRUB
SHUCK
SHUNT
SIEGE
SINEW
SINGE
SIREN
SLATE
SLEEK
SLEET
SLICK
SLIME
SLIMY
SLING
SLOSH
SLOTH
SMALL
SMEAR
SMELT
SMILE
SMIRK
SMITE
SMITH
SMOKE
SNARE
SNARL
SNEER
SNIDE
SNIFF
SNORE
SNORT
SNOUT
SNOWY
SOBER
SOGGY
SOLAR
SOLVE
SONAR
SONIC
SOOTH
SOOTY
SORRY
SOUND
SOUTH
SPACE
SPADE
SPARE
SPARK
SPAWN
SPEAK
SPEAR
SPECK
SPEED
SPELL
SPELT
SPEND
SPENT
SPIED
SPIEL
SPIKE
SPIKY
SPILL
SPINE
SPINY
SPIRE
SPITE
SPLAT
SPLIT

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,337 @@
ALLOY
ALPHA
AMINO
ARRAY
ASSAY
AUDIO
AXIAL
AXIOM
AZURE
BATCH
BATON
BIOME
BIPED
CACHE
CALYX
CARET
CASES
CASTS
CELLS
CHIPS
CHORD
CHUNK
CIRCA
CITED
CLAMP
CLONE
CLOUD
CODON
COILS
COMET
CORAL
CORES
CRAMP
CRANK
CREST
CRUST
CRYPT
CUBIC
CUBIT
CURVE
CYCAD
CYCLE
CYNIC
CYSTS
DATUM
DEBUG
DECAF
DECAL
DECAY
DECOR
DECOY
DEFER
DEFOG
DELTA
DENSE
DEPOT
DEPTH
DETOX
DIODE
DIPPY
DISCO
DISCS
DISKS
DOPED
DOPER
DOSES
DRAFT
DRAIN
DRIFT
DRILL
DRONE
DRUPE
DUALS
DUREX
DWELL
EBOOK
EDEMA
ELUTE
EMAIL
EMCEE
EMEND
EMIRS
EMITS
EMOTE
EPOCH
EPOXY
ERGOT
ERUPT
ESTER
ETHER
ETHIC
ETHOS
EUROS
EVADE
EXACT
EXALT
EXECS
EXERT
EXILE
EXIST
EXITS
EXPAT
EXPEL
EXPOS
EXTRA
EXUDE
EXULT
EXURB
FECAL
FECES
FEMUR
FERMI
FETAL
FETUS
FIBER
FIBRE
FIELD
FILES
FILTH
FINAL
FINED
FINER
FINIS
FINNY
FIORD
FIXED
FIXER
FIZZY
FJORD
FLAGS
FLASK
FLECK
FLEXS
FLINT
FLOAT
FLORA
FLOUR
FLUKY
FLUME
FLUOR
FLUSH
FOCAL
FOCUS
FOILS
FONTS
FORCE
FORMS
FORTE
FORUM
FOSSE
FOXED
FRAME
FREED
FRESH
FRITS
FROND
FROST
FROTH
FUGAL
FUGUE
FUMED
FUMES
FUNGI
FUNGO
FURLS
FUROR
FURTH
FUSED
FUSEE
FUSEL
FUSES
FUTON
FUZED
FUZES
FUZZY
GAGES
GALES
GAMMA
GANGS
GASES
GATED
GATES
GAUGE
GAUNT
GAUSS
GAUZE
GAVEL
GEARS
GECKO
GEEKS
GEESE
GENES
GENIE
GENII
GENRE
GENUS
GEODE
GERMS
GESSO
GIDDY
GILDS
GILLS
GIMPS
GIRTH
GISMO
GIZMO
GLAND
GLASS
GLAZE
GLEAM
GLEAN
GLIDE
GLIMS
GLINT
GLITZ
GLOBE
GLOBS
GLOPS
GLOSS
GLOWS
GLOZE
GLUED
GLUES
GLUEY
GLUMS
GLUON
GLUTE
GLUTS
GLYPH
GNASH
GNOME
GONAD
GONGS
GOODS
GOUGE
GOURD
GOUTS
GRADE
GRADS
GRAFT
GRAIN
GRAMS
GRAPH
GRASP
GRATE
GRAVE
GRAYS
GRAZE
GREBE
GREED
GREYS
GRIDE
GRIDS
GRIFF
GRIFT
GRILL
GRIME
GRIMY
GRIND
GRINS
GRIPE
GRIPS
GRIST
GRITS
GROAN
GROAT
GROGS
GROIN
GROOM
GROPE
GROSS
GROTS
GROUP
GROUT
GROVE
GROWL
GROWN
GROWS
GRUBS
GRUEL
GRUFF
GRUMP
GRUNT
GUANO
GUARD
GUAVA
GUESS
GUEST
GUIDE
HELIX
HERTZ
HEXAD
HEXED
HEXES
HYENA
HYOID
HYPED
HYPER
HYPES
HYPHA
HYPOS
ICHOR
ICONS
IDEAL
IDEAS
IDOLS
IMAGE
IMBED
IMBUE
IMPEL
INANE
INBOX
INCUR
INDEX
INDIE
INERT
INFER
INFIX
INKLE
INLAY
INLET
INNER
INPUT
INRUN
INTER
INTRO
INURE
INURN
INVAR
IODIC
IODID
IODIN
IONIC
IOTAS
IRADE
IRATE
IRIDS

File diff suppressed because it is too large Load Diff