Added all previous files
This commit is contained in:
parent
4466ee8a4c
commit
f04fb2189a
59 changed files with 64921 additions and 0 deletions
18
lab8/Makefile
Normal file
18
lab8/Makefile
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
CMP = gcc
|
||||
FUNC = crossfunc
|
||||
MAIN = crossword
|
||||
EXEC = runcrossword
|
||||
|
||||
$(EXEC): $(FUNC).o $(MAIN).o
|
||||
$(CMP) $(FUNC).o $(MAIN).o -o $(EXEC)
|
||||
|
||||
$(FUNC).o: $(FUNC).c $(FUNC).h
|
||||
$(CMP) -c $(FUNC).c -o $(FUNC).o
|
||||
|
||||
$(MAIN).o: $(MAIN).c $(FUNC).h
|
||||
$(CMP) -c $(MAIN).c -o $(MAIN).o
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
rm $(EXEC)
|
||||
|
||||
317
lab8/crossfunc.c
Normal file
317
lab8/crossfunc.c
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
// Author: Owen Dorweiler
|
||||
// Class: Fundamentals of Computing
|
||||
// Assignment: Lab 8
|
||||
// Due: 17 November 2024
|
||||
|
||||
#include "crossfunc.h"
|
||||
|
||||
void initBoard(char solBoard[][BOARD_SIZE]) {
|
||||
for (int j = 0; j < BOARD_SIZE; j++) {
|
||||
for (int i = 0; i < BOARD_SIZE; i++)
|
||||
solBoard[i][j] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
int getUserWords(Wordstruct words[]) {
|
||||
char userWord[MAX_LENGTH + 1];
|
||||
int wordCount = 0;
|
||||
|
||||
printf("Enter word list:\n");
|
||||
|
||||
// Read in words until '.' is read or there are 20 words
|
||||
scanf("%s", userWord);
|
||||
do {
|
||||
// Check validity of words and add them to array if valid
|
||||
if (validWord(userWord)) {
|
||||
strcpy(words[wordCount].word, userWord);
|
||||
wordCount++;
|
||||
}
|
||||
else printf("^ Word is invalid and will be ignored.\n");
|
||||
|
||||
scanf("%s", userWord);
|
||||
} while (strcmp(userWord, ".") != 0 && wordCount != MAX_WORDS);
|
||||
|
||||
return wordCount;
|
||||
}
|
||||
|
||||
int getFileWords(Wordstruct words[], char *filename) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
printf("File could not be opened. Exiting...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char fileWord[100];
|
||||
int wordCount = 0;
|
||||
|
||||
// Read words until "." is read or there are 20 words
|
||||
while (fgets(fileWord, 100, file) != NULL) {
|
||||
fileWord[strcspn(fileWord, "\n")] = 0;
|
||||
|
||||
// Check validity of words and add them to array if valid
|
||||
if (strcmp(fileWord, ".") != 0 && wordCount != MAX_WORDS) {
|
||||
if (validWord(fileWord)) {
|
||||
strcpy(words[wordCount].word, fileWord);
|
||||
wordCount++;
|
||||
}
|
||||
else printf("\"%s\" is invalid and will be ignored.\n", fileWord);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
return wordCount;
|
||||
}
|
||||
|
||||
bool validWord(char word[]) {
|
||||
bool allLetters = true;
|
||||
for (int a = 0; a < strlen(word); a++) {
|
||||
if (!isalpha(word[a]))
|
||||
allLetters = false;
|
||||
}
|
||||
|
||||
bool correctLength = true;
|
||||
if (strlen(word) < 2 || strlen(word) > MAX_LENGTH)
|
||||
correctLength = false;
|
||||
|
||||
if (allLetters && correctLength)
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void processWords(Wordstruct words[], int numWords) {
|
||||
int wordLength[numWords];
|
||||
|
||||
// Capitalize all words, set placed variables to false
|
||||
for (int a = 0; a < numWords; a++) {
|
||||
for (int b = 0; b < strlen(words[a].word); b++) {
|
||||
words[a].word[b] = toupper(words[a].word[b]);
|
||||
}
|
||||
words[a].placed = false;
|
||||
}
|
||||
|
||||
// Sort the words list longest to shortest
|
||||
bool swapped;
|
||||
char temp[16];
|
||||
do {
|
||||
swapped = false;
|
||||
for (int a = 0; a < numWords - 1; a++) {
|
||||
if (strlen(words[a].word) < strlen(words[a+1].word)) {
|
||||
strcpy(temp, words[a].word);
|
||||
strcpy(words[a].word, words[a+1].word);
|
||||
strcpy(words[a+1].word, temp);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
} while (swapped);
|
||||
}
|
||||
|
||||
void placeWords(char board[][BOARD_SIZE], Wordstruct words[], int numWords) {
|
||||
|
||||
// Place the first word
|
||||
strcpy(words[0].direc, "Across");
|
||||
words[0].x = ceil(BOARD_SIZE / 2) - ceil(strlen(words[0].word) / 2);
|
||||
words[0].y = ceil(BOARD_SIZE / 2);
|
||||
updateBoard(board, words[0]);
|
||||
words[0].placed = true;
|
||||
|
||||
// If crossword only has one word, break
|
||||
if (numWords == 1) return;
|
||||
|
||||
// Define variables
|
||||
int numPlaced = 1;
|
||||
char prevDirec[7] = "Across";
|
||||
bool wordPlaced;
|
||||
|
||||
// Loop through words 2-end; continue while at least one word is placed per cycle
|
||||
do {
|
||||
wordPlaced = false;
|
||||
for (int currentWord = 1; currentWord < numWords; currentWord++) {
|
||||
// If word has not been placed, start the process to place it
|
||||
if (!words[currentWord].placed) {
|
||||
// Define direction based on direction of previous placed word
|
||||
if (strcmp(prevDirec, "Across") == 0)
|
||||
strcpy(words[currentWord].direc, "Down");
|
||||
else strcpy(words[currentWord].direc, "Across");
|
||||
|
||||
// Call search function, which will place word if possible
|
||||
if (search(board, &words[currentWord])) {
|
||||
words[currentWord].placed = true;
|
||||
wordPlaced = true;
|
||||
strcpy(prevDirec, words[currentWord].direc);
|
||||
numPlaced++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If all words have been placed, break the loop
|
||||
if (numWords == numPlaced)
|
||||
break;
|
||||
} while (wordPlaced);
|
||||
}
|
||||
|
||||
bool search(char board[][BOARD_SIZE], Wordstruct *word) {
|
||||
for (int letterIndex = 0; letterIndex < strlen((*word).word); letterIndex++) {
|
||||
for (int y = 0; y < BOARD_SIZE; y++) {
|
||||
for (int x = 0; x < BOARD_SIZE; x++) {
|
||||
if ((*word).word[letterIndex] == board[x][y]) {
|
||||
// Try to place word if match is found
|
||||
if (attemptPlace(board, word, letterIndex, x, y))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool attemptPlace(char board[][BOARD_SIZE], Wordstruct *word, int letterIndex, int x, int y) {
|
||||
// Find potential start and end coordinates
|
||||
if (strcmp((*word).direc, "Across") == 0) {
|
||||
(*word).x = x - letterIndex;
|
||||
(*word).y = y;
|
||||
}
|
||||
else if (strcmp((*word).direc, "Down") == 0) {
|
||||
(*word).x = x;
|
||||
(*word).y = y - letterIndex;
|
||||
}
|
||||
|
||||
// Check if word has valid placement; if so, add to board, if not, keep searching
|
||||
if (validPlace(board, *word)) {
|
||||
updateBoard(board, *word);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validPlace(char board[][BOARD_SIZE], Wordstruct word) {
|
||||
// Check horizontal words
|
||||
if (strcmp(word.direc, "Across") == 0) {
|
||||
// Check if word would fit on board
|
||||
if (word.x < 0 || word.x + strlen(word.word) - 1 > BOARD_SIZE)
|
||||
return false;
|
||||
|
||||
// Check to the left and right of the word
|
||||
if (word.x - 1 >= 0 && board[word.x - 1][word.y] != '.')
|
||||
return false;
|
||||
if (word.x + strlen(word.word) <= BOARD_SIZE && board[word.x + strlen(word.word)][word.y] != '.')
|
||||
return false;
|
||||
|
||||
// Check above and below word
|
||||
for (int a = 0; a < strlen(word.word); a++) {
|
||||
// Check above and below only if letter is not already on board
|
||||
if (word.word[a] != board[word.x + a][word.y]) {
|
||||
if (word.y - 1 >= 0 && board[word.x + a][word.y - 1] != '.')
|
||||
return false;
|
||||
if (word.y + 1 <= BOARD_SIZE && board[word.x + a][word.y + 1] != '.')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Check vertical words
|
||||
else if (strcmp(word.direc, "Down") == 0) {
|
||||
// Check if word would fit on board
|
||||
if (word.y < 0 || word.y + strlen(word.word) - 1 > BOARD_SIZE)
|
||||
return false;
|
||||
|
||||
// Check above and below word
|
||||
if (word.y - 1 >= 0 && board[word.x][word.y - 1] != '.')
|
||||
return false;
|
||||
if (word.y + strlen(word.word) <= BOARD_SIZE && board[word.x][word.y + strlen(word.word)] != '.')
|
||||
return false;
|
||||
|
||||
// Check to the left and right of the word
|
||||
for (int a = 0; a < strlen(word.word); a++) {
|
||||
// Check to the left and right only if letter is not already on board
|
||||
if (word.word[a] != board[word.x][word.y + a]) {
|
||||
if (word.x - 1 >= 0 && board[word.x - 1][word.y + a] != '.')
|
||||
return false;
|
||||
if (word.x + 1 <= BOARD_SIZE && board[word.x + 1][word.y + a] != '.')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateBoard(char board[][BOARD_SIZE], Wordstruct word) {
|
||||
// Place words horizontally or vertically depending on direction
|
||||
if (strcmp(word.direc, "Across") == 0) {
|
||||
for (int a = 0; a < strlen(word.word); a++)
|
||||
board[word.x + a][word.y] = word.word[a];
|
||||
}
|
||||
else if (strcmp(word.direc, "Down") == 0) {
|
||||
for (int a = 0; a < strlen(word.word); a++)
|
||||
board[word.x][word.y + a] = word.word[a];
|
||||
}
|
||||
}
|
||||
|
||||
void printBoards(char board[][BOARD_SIZE]) {
|
||||
printf("\nSolution:\n");
|
||||
|
||||
// Print solution board within border
|
||||
printBorder();
|
||||
for (int y = 0; y < BOARD_SIZE; y++) {
|
||||
printf("|");
|
||||
for (int x = 0; x < BOARD_SIZE; x++)
|
||||
printf("%c", board[x][y]);
|
||||
printf("|\n");
|
||||
}
|
||||
printBorder();
|
||||
|
||||
printf("\nCrossword puzzle:\n");
|
||||
|
||||
// Print puzzle board within border
|
||||
printBorder();
|
||||
for (int y = 0; y < BOARD_SIZE; y++) {
|
||||
printf("|");
|
||||
for (int x = 0; x < BOARD_SIZE; x++) {
|
||||
if (board[x][y] == '.')
|
||||
printf("#");
|
||||
else printf(" ");
|
||||
}
|
||||
printf("|\n");
|
||||
}
|
||||
printBorder();
|
||||
}
|
||||
|
||||
void printBorder() {
|
||||
for (int i = 0; i < BOARD_SIZE + 2; i++)
|
||||
printf("-");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void randomize(Wordstruct words[], int numWords) {
|
||||
srand(time(NULL));
|
||||
|
||||
// Generate a scrambled version of each word
|
||||
for (int a = 0; a < numWords; a++) {
|
||||
strcpy(words[a].scrambled, words[a].word);
|
||||
for (int i = strlen(words[a].scrambled) - 1; i > 0; i--) {
|
||||
int j = rand() % (i + 1);
|
||||
char temp = words[a].scrambled[i];
|
||||
words[a].scrambled[i] = words[a].scrambled[j];
|
||||
words[a].scrambled[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Rearrange word struct randomly
|
||||
for (int i = numWords - 1; i > 0; i--) {
|
||||
int j = rand() % (i + 1);
|
||||
Wordstruct temp = words[i];
|
||||
words[i] = words[j];
|
||||
words[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void printClues(Wordstruct words[], int numWords) {
|
||||
printf("\nClues:\n");
|
||||
|
||||
for (int a = 0; a < numWords; a++)
|
||||
if (words[a].placed)
|
||||
printf("%2d %2d %-6s %s\n", words[a].x, words[a].y, words[a].direc, words[a].scrambled);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
42
lab8/crossfunc.h
Normal file
42
lab8/crossfunc.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Author: Owen Dorweiler
|
||||
// Class: Fundamentals of Computing
|
||||
// Assignment: Lab 8
|
||||
// Due: 17 November 2024
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#define BOARD_SIZE 15
|
||||
#define MAX_WORDS 20
|
||||
#define MAX_LENGTH 15
|
||||
|
||||
typedef struct {
|
||||
char word[MAX_LENGTH];
|
||||
char scrambled[MAX_LENGTH];
|
||||
char direc[7];
|
||||
int x;
|
||||
int y;
|
||||
bool placed;
|
||||
} Wordstruct;
|
||||
|
||||
void initBoard(char [][BOARD_SIZE]);
|
||||
int getUserWords(Wordstruct words[]);
|
||||
int getFileWords(Wordstruct words[], char []);
|
||||
bool validWord(char []);
|
||||
void processWords(Wordstruct words[], int);
|
||||
|
||||
void placeWords(char [][BOARD_SIZE], Wordstruct words[], int);
|
||||
bool search(char [][BOARD_SIZE], Wordstruct *word);
|
||||
bool attemptPlace (char [][BOARD_SIZE], Wordstruct *word, int, int, int);
|
||||
bool validPlace(char [][BOARD_SIZE], Wordstruct word);
|
||||
void updateBoard(char [][BOARD_SIZE], Wordstruct word);
|
||||
|
||||
void printBoards(char [][BOARD_SIZE]);
|
||||
void printBorder();
|
||||
void randomize(Wordstruct words[], int);
|
||||
void printClues(Wordstruct words[], int);
|
||||
53
lab8/crossword.c
Normal file
53
lab8/crossword.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Author: Owen Dorweiler
|
||||
// Class: Fundamentals of Computing
|
||||
// Assignment: Lab 8
|
||||
// Due: 17 November 2024
|
||||
|
||||
#include "crossfunc.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
//Initialize solution board
|
||||
char board[BOARD_SIZE][BOARD_SIZE];
|
||||
initBoard(board);
|
||||
|
||||
// Initialize words list and numWords
|
||||
Wordstruct words[MAX_WORDS];
|
||||
int numWords;
|
||||
|
||||
printf("\nCrossword Generator\n-------------------\n\n");
|
||||
|
||||
if (argc == 1)
|
||||
// Get words from user and return number of words
|
||||
numWords = getUserWords(words);
|
||||
else if (argc == 2)
|
||||
// Read in the words from file and return number of words
|
||||
numWords = getFileWords(words, argv[1]);
|
||||
else if (argc == 3) {
|
||||
freopen(argv[2], "w", stdout);
|
||||
numWords = getFileWords(words, argv[1]);
|
||||
}
|
||||
else printf("Wrong number of arguments. Restart and try again.");
|
||||
|
||||
// End program if no words or getFileWords returned error
|
||||
if (numWords == 0) abort();
|
||||
|
||||
// Process and place the words
|
||||
processWords(words, numWords);
|
||||
placeWords(board, words, numWords);
|
||||
|
||||
randomize(words, numWords);
|
||||
|
||||
// Print words that could not be placed
|
||||
for (int a = 0; a < numWords; a++)
|
||||
if (!words[a].placed)
|
||||
printf("\"%s\" could not be placed.\n", words[a].word);
|
||||
|
||||
// Print boards and clues
|
||||
printBoards(board);
|
||||
printClues(words, numWords);
|
||||
|
||||
// Close stdout if writing to file
|
||||
if (argc == 3) fclose(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
13
lab8/mywords.txt
Normal file
13
lab8/mywords.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
NotreDame
|
||||
fightingirish
|
||||
UND
|
||||
computer
|
||||
CSE
|
||||
programming
|
||||
keyboard
|
||||
code
|
||||
function
|
||||
loop
|
||||
not
|
||||
if
|
||||
.
|
||||
Loading…
Reference in a new issue