-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit of projects ported to eclipse
- Loading branch information
Showing
9 changed files
with
622 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* 31-game.c | ||
* Copyright (c) 2014 Naomi Dickerson and Parker Harris Emerson | ||
* Given a partially played game of 31, calculate who will win if both parties subsequently play optimally. | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <math.h> | ||
#include "game_tree.h" | ||
|
||
|
||
int main(){ | ||
int cards[14]; | ||
int cardIndex = 0; | ||
char nextChar; | ||
|
||
FILE *fileHandle; //the file containing game 31 data | ||
fileHandle = fopen("cardData.txt","r"); | ||
|
||
// check for file open error | ||
if (fileHandle == NULL) { | ||
printf("\nUnable to open game 31 text data\n"); | ||
exit(1); | ||
} | ||
|
||
while (1) { // Outer loop for file. | ||
// Clear vars. | ||
for (int i = 0; i < 14; i++) { | ||
cards[i] = 0; | ||
} | ||
cardIndex = 0; | ||
|
||
while (1) { // Inner loop for each game. | ||
fscanf(fileHandle, "%c", &nextChar); | ||
if (nextChar - 48 < 0 || nextChar - 48 > 6) { | ||
break; | ||
} | ||
if (nextChar - 48 == 0) { | ||
printf("\nEnd of file.\n\n"); | ||
exit(0); | ||
} | ||
cards[cardIndex] = (int)(nextChar - 48); | ||
cardIndex++; | ||
} | ||
|
||
// Print game. | ||
for (int i = 0; i < 14; i++) { | ||
if (cards[i]) { | ||
printf("%d", cards[i]); | ||
} | ||
} | ||
int winner; | ||
node gameRoot = { 0 }; | ||
treeCreate(&gameRoot); // Create root node. | ||
// Copy starting state into root node. | ||
for (int i = 0; i < 14; i++) { | ||
gameRoot.state[i] = cards[i]; | ||
} | ||
gameRoot.owner = 1 + (cardIndex % 2); | ||
|
||
treePopulate(&gameRoot); | ||
if (gameRoot.isLeaf) { | ||
winner = cardIndex % 2; | ||
} else { | ||
winner = miniMax(&gameRoot); | ||
} | ||
|
||
if (winner == 1) { | ||
printf("\tA"); | ||
} else { | ||
printf("\tB"); | ||
} | ||
|
||
printf("\n"); | ||
|
||
for (int i = 0; i < 6; i++) { | ||
if (gameRoot.child[i]) { | ||
treeDestroy(gameRoot.child[i]); | ||
} | ||
} | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* game_tree.h | ||
* | ||
* Provides game_tree structure for 31-game.c | ||
* Naomi Dickerson and Parker Harris Emerson 2014 | ||
* | ||
*/ | ||
|
||
#ifndef GAME_TREE_H_ | ||
#define GAME_TREE_H_ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
typedef struct game_node { | ||
// Creates node containing the game state, the node's | ||
// 'owner', whether or not it is a leaf (final state) and | ||
// 6 child nodes. | ||
int owner; | ||
int state[14]; | ||
int isLeaf; | ||
struct game_node* child[6]; | ||
} node; | ||
|
||
int legalState(int num, int* cur_state) { | ||
// takes a number "num" (1-6) and sees if it is a valid | ||
// play given a current game state "cur_state". If yes, | ||
// return 1. Else return 0. | ||
int total = 0; | ||
int total_num = 0; | ||
int i = 0; | ||
while (cur_state[i] != 0) { | ||
total += cur_state[i]; | ||
if (cur_state[i] == num) { | ||
total_num += 1; | ||
} | ||
i++; | ||
} | ||
// The card is illegal if it brings the total above 31 or | ||
// there are already 4 of the card in play. | ||
if ((total + num) > 31 || total_num >= 4) { | ||
return 0; | ||
} | ||
return 1; | ||
} | ||
|
||
void addCard(int num, node* nodeNew) { | ||
// Finds the first '0' entry in the state array passed in, | ||
// and appends the given int (card number) at that position. | ||
int i = 0; | ||
while (nodeNew->state[i] != 0) { | ||
i++; | ||
} | ||
nodeNew->state[i] = num; | ||
// A's move | ||
if ((i % 2) == 1) { | ||
nodeNew->owner = 1; | ||
// B's move | ||
} else { | ||
nodeNew->owner = 2; | ||
} | ||
} | ||
|
||
void treeCreate(node* nodeRoot) { | ||
for (int i = 0; i < 14; i++) { | ||
nodeRoot->state[i] = 0; | ||
} | ||
|
||
for (int i = 0; i < 6; i++) { | ||
nodeRoot->child[i] = NULL; | ||
} | ||
} | ||
|
||
node* nodeCreate(int card, node* nodeRoot) { | ||
node* nodeNew = (node*) (malloc(sizeof(node))); | ||
for (int i = 0; i < 14; i++) { | ||
nodeNew->state[i] = nodeRoot->state[i]; | ||
} | ||
// Appends the new card to the existing game state | ||
addCard(card, nodeNew); | ||
for (int i = 0; i < 6; i++) { | ||
nodeNew->child[i] = NULL; | ||
} | ||
return nodeNew; | ||
} | ||
|
||
void treePopulate(node* nodeRoot) { | ||
// Generates all legal games from a given root | ||
int hasChild = 0; | ||
for (int i = 0; i < 6; i++) { | ||
// Check if adding that child creates a legal game state | ||
if (legalState((i + 1), nodeRoot->state)) { | ||
// If it is a legal game state, create a variable | ||
// with the new state to pass to the child | ||
nodeRoot->child[i] = nodeCreate(i + 1, nodeRoot); | ||
treePopulate(nodeRoot->child[i]); | ||
hasChild++; | ||
} | ||
} | ||
if (!hasChild) { | ||
nodeRoot->isLeaf = 1; | ||
} | ||
} | ||
|
||
int miniMax(node* nodeRoot) { | ||
// Test if it is a leaf, i.e. the base case of the recursion | ||
if (nodeRoot->isLeaf) { | ||
if (nodeRoot->owner == 1) { | ||
return 1; | ||
} else { | ||
return -1; | ||
} | ||
} else { | ||
// Otherwise, if not leaf: | ||
//(stop searching if the greatest possible max/min found sooner) | ||
if (nodeRoot->owner == 1) { | ||
for (int i = 0; i < 6; i++) { | ||
if (nodeRoot->child[i] && miniMax(nodeRoot->child[i]) == 1) { | ||
return 1; | ||
} | ||
} | ||
// This should return -1 only if all of the children are -1 | ||
return -1; | ||
} else { | ||
for (int i = 0; i < 6; i++) { | ||
if (nodeRoot->child[i] && miniMax(nodeRoot->child[i]) == -1) { | ||
return -1; | ||
} | ||
} | ||
// opposite of above, returns the min, | ||
// so only returns 1 if all children are 1 | ||
return 1; | ||
} | ||
} | ||
} | ||
|
||
void treeDestroy(node* nodeRoot) { | ||
|
||
if (nodeRoot == NULL) { | ||
return; | ||
} | ||
|
||
for (int i = 0; i < 6; i++) { | ||
treeDestroy(nodeRoot->child[i]); | ||
} | ||
free(nodeRoot); | ||
} | ||
|
||
#endif /* GAME_TREE_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* generate-numbers.c | ||
* | ||
* Created on: Nov 23, 2014 | ||
* Author: nome | ||
*/ | ||
|
||
#include <stdio.h> | ||
|
||
int main() { | ||
for (int i = 0; i < 1000; i++) { | ||
printf("%d ", i); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* matrix-product.c | ||
* | ||
* Created on: Nov 24, 2014 | ||
* Author: nome | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
int main() { | ||
int size = 0; // This is the row and column dimension of the matrices | ||
int* matrix1 = NULL; | ||
int* matrix2 = NULL; | ||
int* product = NULL; | ||
int accumulator = 0; | ||
|
||
FILE* fileHandle = fopen("Data4.txt", "r"); | ||
|
||
fscanf(fileHandle, "%d", &size); | ||
|
||
// Allocate space for 3 matrices of equal dimensions. The | ||
// matrices are represented by a 1-dimensional array and are of | ||
// length nxn (size x size). | ||
matrix1 = (int*) (malloc(sizeof(int) * size * size)); | ||
matrix2 = (int*) (malloc(sizeof(int) * size * size)); | ||
product = (int*) (malloc(sizeof(int) * size * size)); | ||
|
||
for (int i = 0; i < size * size; i++) { | ||
fscanf(fileHandle, "%d", &matrix1[i]); | ||
} | ||
|
||
for (int i = 0; i < size * size; i++) { | ||
fscanf(fileHandle, "%d", &matrix2[i]); | ||
} | ||
|
||
fclose(fileHandle); | ||
|
||
{ | ||
// My algorithm is based on the observation that (with respect to | ||
// square matrix dimensions) all elements of | ||
// a row have the same integer-division result, and all elements of | ||
// a column are the same modulus. This allows one extra loop | ||
// to be cut out! | ||
|
||
int row_start; | ||
int column_start; | ||
|
||
for (int i = 0; i < size * size; i++) { | ||
row_start = (i/size) * size; | ||
column_start = i % size; | ||
accumulator = 0; | ||
|
||
for (int j = 0; j < size; j++) { | ||
accumulator += matrix1[row_start + j] * | ||
matrix2[column_start + (j * size)]; | ||
} | ||
|
||
product[i] = accumulator; | ||
|
||
} | ||
|
||
|
||
printf("\nThe product is:\n["); | ||
|
||
for (int i = 0; i < size * size; i++) { | ||
|
||
if (i % size == 0) | ||
printf("\n"); | ||
|
||
printf("%d ", product[i]); | ||
} | ||
printf("]\n"); | ||
|
||
|
||
} | ||
|
||
free(matrix1); | ||
free(matrix2); | ||
free(product); | ||
|
||
return 0; | ||
} | ||
|
Oops, something went wrong.