Skip to content

Instantly share code, notes, and snippets.

@atondwal
Last active February 2, 2020 08:18
Show Gist options
  • Save atondwal/73d5b77c2669188086d704a10fd24fba to your computer and use it in GitHub Desktop.
Save atondwal/73d5b77c2669188086d704a10fd24fba to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
static int MapSizeRow = 10 + 2; //map size with boundaries in vertical direction
static int MapSizeCol = 20 + 2; //map size with boundaries in horizontal direction
static int ItemRow = 10;
static int ItemCol = 10;
static int TextBoxRow = 3 + 2;
static int TextBoxCol = 20 + 2;
struct item_s {
wchar_t glyph;
int x;
int y;
int heldByMapP;
};
typedef struct item_s item_t;
void render_field(wchar_t *ptr, int rowMax, int colMax) { //Renders the Map on the Computer Screen using the map pointer
for (int i = 0; i < rowMax; i++){
for(int j = 0; j < colMax; j++){
wprintf(L"%lc", *(ptr + i*colMax + j) ); //Renders row
}
wprintf(L"\n"); //New row
}
}
void initialize_inventory(wchar_t *ptr, int rowMax, int colMax) //Prints "Inventory" in the text field
{
char invString[9] = "Inventory";
for (int i = 0; i < 9; i++){
*(ptr + colMax + 1 + i) = invString[i];
}
}
void initialize_items(wchar_t *mptr, wchar_t *itemFieldPtr, item_t *items, int aCol, int colMaxMap, int colMaxItem) //places the items in the map array
{
for( int i = 0; i < aCol; i++) //loops through for however many items there are
{
if(items[i].heldByMapP)
{
mptr[items[i].x *colMaxMap + items[i].y] = items[i].glyph;
itemFieldPtr[items[i].x *colMaxMap + items[i].y] = items[i].glyph;
}
}
}
void initialize_field(wchar_t *ptr, int rowMax, int colMax, int inv, int item) { //Prepares the fields for rendering
for (int i = 0; i < rowMax; i++){ //Set map to blank
for(int j = 0; j < colMax; j++){
*(ptr + i*colMax + j) = 0x00A0; //unicode for nbsp
}
}
if(item != 1)
{
for (int i = 0; i < colMax; i++) //Top and Bottom Boundaries
{
*(ptr+i) = 0x2550; //top row unicode for graphical boundary
*(ptr+i+(colMax*(rowMax-1))) = 0x2550; //bottom row unicode for graphical boundary
}
for (int i = 0; i < rowMax; i++ ) //Left and Right Boundaries
{
*(ptr+i*colMax) = 0x2551; //left column unicode for graphical boundary
*(ptr+i*colMax+colMax-1) = 0x2551; //right column unicode for graphical boundary
}
*(ptr+0) = 0x2554; //top left corner
*(ptr+colMax-1) = 0x2557; //top right corner
*(ptr+colMax*rowMax-1) = 0x255D; //bottom left corner
*(ptr+colMax*(rowMax-1)) = 0x255A; //bottom right corner
}
if(inv)
{
initialize_inventory(ptr, rowMax, colMax);
}
}
void place_items(wchar_t *iptr, wchar_t *mptr) //Updates the item field with Map
{
for (int i = 0; i < MapSizeRow; i++){
for(int j = 0; j < MapSizeCol; j++){
*(iptr + i*MapSizeCol + j) = *(mptr + i*MapSizeCol + j); //Copies the map field to the item field
}
}
}
void update_player(wchar_t *ptr, int co[2], int MapSizeCol) //sets the player position on the map
{
*(ptr + MapSizeCol*co[0] + co[1]) = 0x0041; //unicode for A
}
//Grabs the item on the player to the inventory
void grabItem(wchar_t *ifptr, wchar_t *tptr, item_t *items, int aRow, int co[2])
{
int i = 0;
if( *(ifptr + (co[0])*MapSizeCol + co[1]) != 0x00A0 ) //if the player is on something
{
while(i < TextBoxCol)
{
if( *(tptr + 2*TextBoxCol + i) == 0x00A0) //if the inventory space is empty
{
*(tptr + 2*TextBoxCol + i) = *(ifptr + (co[0])*MapSizeCol + co[1]); //place item
for(int j = 0; j < aRow; j++){
if(items[j].x == co[0] && items[j].y == co[1])
{
items[j].heldByMapP = 0; //Turns off item when items are updated on the field
break;
}
}
break;
}
else
{
i++;
}
}
}
}
/*
* Terminal Mode Handling
*/
// initial terminal IO settings
struct termios initial;
// Restore initial terminal IO settings
void restore(void) {
tcsetattr(1, TCSANOW, &initial);
}
// Initialize terminal into non-canonnical mode (read character-by-character)
// c.f. http://xn--rpa.cc/irl/term.html
void terminit(void) {
struct termios t;
tcgetattr(1, &initial);
t = initial;
t.c_lflag &= (~ECHO & ~ICANON);
atexit(restore);
tcsetattr(1, TCSANOW, &t);
}
/*
* main loop
*/
int main( void ) {
setlocale(LC_CTYPE, "");
terminit();
wchar_t mapField[MapSizeRow][MapSizeCol]; //map 2d array
wchar_t *mapPtr = &mapField[0][0]; //map array pointer
wchar_t textField[TextBoxRow][TextBoxCol]; //text 2d array
wchar_t *textPtr = &textField[0][0]; //text array pointer
item_t itemMap[4] = //items and their locations
{(item_t){ .glyph=0x2660, .x=4, .y=14, .heldByMapP=1},
(item_t){ .glyph=0x2665, .x=3, .y=7, .heldByMapP=1},
(item_t){ .glyph=0x2666, .x=8, .y=2, .heldByMapP=1},
(item_t){ .glyph=0x2663, .x=6, .y=12, .heldByMapP=1}};
int itemMapCol = *(&itemMap + 1) - itemMap;
wchar_t itemField[MapSizeRow][MapSizeCol]; //item 2d array
wchar_t *itemPtr = &itemField[0][0]; //item array pointer points to the inside of the map
char userInput = 'A';
int playerLocation[2] = {5, 3}; //player row and col coordinates
initialize_field(textPtr, TextBoxRow, TextBoxCol, 1, 0); //clear the text field
initialize_field(itemPtr, TextBoxRow, TextBoxCol, 0, 1); //Initializes map field and item field with items
while(userInput != '0')
{
system("clear"); //clears the console
initialize_field(mapPtr, MapSizeRow, MapSizeCol, 0, 0); //clear the map field
initialize_items(mapPtr, itemPtr, itemMap, itemMapCol, MapSizeCol, ItemCol); //Initializes map field and item field with items
place_items(itemPtr, mapPtr); //Updates Item Field
//initialize_items(itemToMapPtr, itemPtr, imap1ptr, itemMapRow, itemMapCol, MapSizeCol, ItemCol);
//initialize_field(itemPtr, MapSizeRow, MapSizeCol, 0, 1);
//initialize_field(itemPtr, TextBoxRow, TextBoxCol, 0, 1);
update_player(mapPtr, playerLocation, MapSizeCol); //place the playerLocation on the map field
render_field(mapPtr, MapSizeRow, MapSizeCol); //rendering map field
//render_field(itemPtr, MapSizeRow, MapSizeCol);
render_field(textPtr, TextBoxRow, TextBoxCol); //rendering text field
wprintf(L"X:%d ", playerLocation[0]);
wprintf(L"Y:%d ", playerLocation[1]);
wprintf(L"\n");
//scanf(" %c", &userInput);
read(1, &userInput, 1);
switch (userInput) //switch statement modifies playerLocation location based on input
{
case 'd': playerLocation[1] = playerLocation[1] < MapSizeCol-2 ? playerLocation[1] + 1 : playerLocation[1]; break; //Moves player right 1
case 'a': playerLocation[1] = playerLocation[1] > 1 ? playerLocation[1] - 1 : playerLocation[1]; break; //Moves player left 1
case 's': playerLocation[0] = playerLocation[0] < MapSizeRow - 2? playerLocation[0] + 1 : playerLocation[0]; break; //Moves player up 1
case 'w': playerLocation[0] = playerLocation[0] > 1 ? playerLocation[0] - 1 : playerLocation[0]; break; //Moves player down 1
case 'e': grabItem(itemPtr, textPtr, itemMap, itemMapCol, playerLocation); break; //Places item in inventory
//case 'e': *textPtr = 0x0050; break;
default: break;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment