Compare commits

...

10 Commits

11 changed files with 305 additions and 103 deletions

50
README.md Normal file
View File

@@ -0,0 +1,50 @@
# Handleiding
Geachte speler,
Heb je wel eens rijk willen zijn?
Vast wel. Mensen met goede bedoelingen (zoals ik) hebben jouw
daarom meermaals geappt op Telegram om je te vragen of je bij een
bedrijf XYZ wilt werken. De werktijden zijn slechts 30 min per
week, en je verdient 500 euro per dag!
Misschien twijfel je nog. Geen probleem! Voor kleine spelers
zoals jij hebben we een spel genaamd 'gambling-curses'. In dit
spel zie je een live grafiek van de laatste Bitcoin-prijs, en heb
je 10.000 euro op je bankaccount. Je kunt gemakkelijk traden door
op 's' en 'b' te klikken. ('s' betekent SELL, 'b' betekent BUY).
Aangezien de cryptomarkt zeker NIET gamblen is, en er wel degelijk
een strategie achter zit, kun je zo gaan oefenen.
Met vriendelijke groet,
Crypto/Dropshipping Guru
## Notes aan de TA's
Beste TA,
Het is nu zaterdagavond, en ik heb besloten om de game te laten
voor wat het is. Ik had de functies nog beter commentaar moeten
geven, de code moeten refactoren, bugs moeten fixen, memory moeten
free()en, ...
Maar daar is nu geen tijd meer voor. Veel dingen in de code zijn
ronduit fout. Als ik nog tijd had, dan had ik de UI-framework
uitgebreid om textboxes te maken, buttonhovers en een betere
algoritme voor het tekenen van de boxes. Ook had ik dan de
pricechart anders geprogrammeerd zodat de prijzen altijd in zicht
blijven en niet buiten de box komen, wat momenteel weleens
gebeurt. (Overigens heb ik hier de NGINX-stijlgids gevolgt.)
Toch is het een geinig spelletje. Geniet ervan.
Met vriendelijke groet,
Artsiom
UvA-Informaticastudent
16141253

126
box.c
View File

@@ -17,10 +17,14 @@
#include "util.h"
static void draw_rectangle(double x, double y, double width, double height);
static void draw_chart(struct box *, double x, double y, double width, double height);
static void draw_container(struct box *, double x, double y, double width, double height);
static void draw_button(struct box *, double x, double y, double width, double height);
static void draw_rectangle(unsigned int x, unsigned int y, unsigned int width,
unsigned int height);
static void draw_chart(struct box *, unsigned int x, unsigned int y,
unsigned int width, unsigned int height);
static void draw_container(struct box *, unsigned int x, unsigned int y,
unsigned int width, unsigned int height);
static void draw_button(struct box *, unsigned int x, unsigned int y,
unsigned int width, unsigned int height);
void
@@ -31,46 +35,42 @@ append_box(struct box *parent, struct box *child)
static void
draw_rectangle(double fx, double fy, double fwidth, double fheight)
draw_rectangle(unsigned int x, unsigned int y, unsigned int width,
unsigned int height)
{
size_t x = llround(fx);
size_t y = llround(fy);
size_t w = llround(fwidth) - 1;
size_t h = llround(fheight) - 1;
/* corners */
ui_char(x, y, '+');
ui_char(x, y + h, '+');
ui_char(x + w, y + h, '+');
ui_char(x + w, y, '+');
ui_char(x, y + height, '+');
ui_char(x + width, y + height, '+');
ui_char(x + width, y, '+');
/* vertical borders */
for (size_t i = 1; i < h; i++) {
for (size_t i = 1; i < height; i++) {
ui_char(x, y + i, '|');
}
for (size_t i = 1; i < h; i++) {
ui_char(x + w, y + i, '|');
for (size_t i = 1; i < height; i++) {
ui_char(x + width, y + i, '|');
}
/* horizontal borders */
for (size_t i = 1; i < w; i++) {
ui_char(x + i, y, '-');
for (size_t i = 1; i < width; i++) {
ui_char(x + i, y, '-');
}
for (size_t i = 1; i < w; i++) {
ui_char(x + i, y + h, '-');
for (size_t i = 1; i < width; i++) {
ui_char(x + i, y + height, '-');
}
}
static void
draw_chart(struct box *chart, double x, double y, double width, double height)
draw_chart(struct box *chart, unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
char c = '@';
long int actual_diff;
double diff, price;
enum ui_color color;
@@ -86,28 +86,18 @@ draw_chart(struct box *chart, double x, double y, double width, double height)
actual_diff = 0;
for (size_t i = 0; i < width; i++) {
diff = (double)rand() / RAND_MAX - 0.6;
actual_diff = (size_t)(height + y - price) - (size_t)(height + y - (price + diff));
price = chart->chart->prices[i];
if (actual_diff > 0) {
color = UI_GREEN;
} else if (actual_diff == 0) {
color = UI_NONE;
} else if (actual_diff < 0) {
color = UI_RED;
}
ui_color_on(color);
ui_char(x + i, height + y - price, c);
ui_color_off(color);
price += diff;
ui_color_on(UI_BLUE);
ui_char(x + i, height + y - price, '@');
ui_color_off(UI_BLUE);
}
}
static void
draw_button(struct box *b, double x, double y, double width, double height)
draw_button(struct box *b, unsigned int x, unsigned int y, unsigned int width,
unsigned int height)
{
ui_color_on(b->color);
draw_rectangle(x, y, width, height);
@@ -117,54 +107,59 @@ draw_button(struct box *b, double x, double y, double width, double height)
static void
draw_container(struct box *b, double x, double y, double width, double height)
draw_container(struct box *b, unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
double current, length, total_fills, pixels_per_fill;
struct box *child;
unsigned int current, i, length, total_fills, pixels_per_fill;
struct box *child;
switch (b->type) {
case BOX_VERTICAL:
length = height;
current = y;
break;
length = height;
current = y;
break;
case BOX_HORIZONTAL:
length = width;
current = x;
break;
length = width;
current = x;
break;
}
total_fills = 0;
for (size_t i = 0; i < b->length; i++) {
total_fills += b->children[i]->fills;
for (i = 0; i < b->length; i++) {
total_fills += b->children[i]->fills;
}
pixels_per_fill = length / total_fills;
for (size_t i = 0; i < b->length; i++) {
child = b->children[i];
length = child->fills * pixels_per_fill;
for (i = 0; i < b->length; i++) {
child = b->children[i];
length = child->fills * pixels_per_fill;
switch (b->type) {
case BOX_VERTICAL: draw_box(child, x, current, width, length); break;
case BOX_HORIZONTAL: draw_box(child, current, y, length, height); break;
}
switch (b->type) {
case BOX_VERTICAL:
draw_box(child, x, current, width, length);
break;
case BOX_HORIZONTAL:
draw_box(child, current, y, length, height);
break;
}
current += length;
current += length;
}
}
struct box *
new_chart_box(void)
new_chart_box(struct chart *chart)
{
struct box *chart = malloc(sizeof(struct box));
struct box *box = malloc(sizeof(struct box));
chart->type = BOX_CHART;
chart->prices = emalloc(sizeof(double) * 100);
chart->fills = 1;
chart->color = UI_NONE;
box->type = BOX_CHART;
box->chart = chart;
box->fills = 1;
box->color = UI_NONE;
return chart;
return box;
}
@@ -211,7 +206,8 @@ new_vertical_box(void)
void
draw_box(struct box *b, double x, double y, double width, double height)
draw_box(struct box *b, unsigned int x, unsigned int y, unsigned int width,
unsigned int height)
{
switch (b->type) {
case BOX_BUTTON:

23
box.h
View File

@@ -8,6 +8,7 @@
#pragma once
#include "chart.h"
#include "ui.h"
@@ -21,24 +22,19 @@ enum box_type {
struct box {
enum box_type type;
enum ui_color color;
double fills;
unsigned int fills;
union {
/* button */
char *name;
/* chart and vertical/horizontal box */
/* chart */
struct chart *chart;
/* vertical/horizontal */
struct {
/* chart and vertical/horizontal box */
size_t length;
union {
/* vertical/horizontal box */
struct box **children;
/* chart */
double *prices;
};
struct box **children;
};
};
};
@@ -47,8 +43,9 @@ struct box {
struct box *new_button_box(char *name);
struct box *new_vertical_box(void);
struct box *new_horizontal_box(void);
struct box *new_chart_box(void);
struct box *new_chart_box(struct chart *);
void append_box(struct box *parent, struct box *child);
void draw_box(struct box *, double x, double y, double width, double height);
void draw_box(struct box *, unsigned int x, unsigned int y, unsigned int width,
unsigned int height);

43
chart.c Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) Artsiom D.
* Copyright (C) shit-co.de
*/
#include <stdlib.h>
#include <string.h>
#include "chart.h"
#include "util.h"
struct chart
new_chart(unsigned int length)
{
unsigned int i;
double price;
struct chart chart;
chart.prices = emalloc(sizeof(double) * length);
chart.length = length;
/* populate with random prices */
price = 10;
for (i = 0; i < length; i++) {
chart.prices[i] = price;
price += (double)rand() / RAND_MAX * 4 - 2;
}
return chart;
}
void
update_chart(struct chart *chart)
{
memmove(chart->prices, chart->prices + 1, (chart->length - 1) * sizeof(double));
chart->prices[chart->length - 1] = chart->prices[chart->length - 2] + (double)rand() / RAND_MAX * 4 - 2;
}

18
chart.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) Artsiom D.
* Copyright (C) shit-co.de
*/
#pragma once
struct chart {
double *prices;
unsigned int length;
};
void update_chart(struct chart *);
struct chart new_chart(unsigned int length);

115
main.c
View File

@@ -5,20 +5,35 @@
*/
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curses.h>
#include <time.h>
#include "box.h"
#include "ui.h"
#include "util.h"
int
main(void)
enum game_state {
GAME_IDLE, /* can buy AND sell */
GAME_BOUGHT, /* cannot buy again */
GAME_SOLD, /* cannot sell again */
};
struct game {
unsigned int dollars;
struct chart chart;
enum game_state state;
};
struct box *
initialize_ui_from_game(struct game *game)
{
struct box *ui, *top, *bottom, *left, *right, *buy, *sell, *scam, *title, *desc;
ui_init();
struct box *ui, *top, *bottom, *left, *right, *buy, *sell, *bank,
*title, *desc;
title = new_button_box("Bitcoin");
desc = new_button_box("A crypto-scam :-)");
@@ -27,20 +42,25 @@ main(void)
append_box(top, title);
append_box(top, desc);
left = new_chart_box();
left = new_chart_box(&game->chart);
left->fills = 5;
buy = new_button_box("buy");
buy->color = UI_GREEN;
sell = new_button_box("sell");
sell->color = UI_RED;
scam = new_button_box("scam");
char *bank_text = emalloc(500);
sprintf(bank_text, "YOU HAVE $%d.", game->dollars);
bank = new_button_box(bank_text);
sell->color = UI_BLUE;
right = new_vertical_box();
append_box(right, buy);
append_box(right, sell);
append_box(right, scam);
append_box(right, bank);
bottom = new_horizontal_box();
bottom->fills = 3;
@@ -51,11 +71,82 @@ main(void)
append_box(ui, top);
append_box(ui, bottom);
draw_box(ui, 0, 0, ui_width()-1, ui_height()-1);
return ui;
}
ui_refresh();
sleep(300);
/*
* Buy 50 coins, price = last price in chart.
*/
void game_buy(struct game *game)
{
if (game->state != GAME_IDLE) {
return;
}
game->dollars -= game->chart.prices[game->chart.length - 1] * 50;
game->state = GAME_BOUGHT;
}
/*
* Sell 50 coins, price = last price in chart.
*/
void game_sell(struct game *game)
{
if (game->state != GAME_BOUGHT) {
return;
}
game->dollars += game->chart.prices[game->chart.length - 1] * 50;
game->state = GAME_IDLE;
}
int
main(void)
{
int framerate;
struct box *ui;
struct game game;
framerate = 10;
game.state = GAME_IDLE;
game.dollars = 10000;
game.chart = new_chart(200);
ui_init();
ui = initialize_ui_from_game(&game);
for (;;) {
draw_box(ui, 0, 0, ui_width(), ui_height());
ui_refresh();
clock_t current = clock();
clock_t max = current + CLOCKS_PER_SEC * (1.0/framerate);
for (;;) {
switch (getch()) {
case 'b':
game_buy(&game);
break;
case 's':
game_sell(&game);
break;
}
if (clock() >= max) {
break;
}
}
update_chart(&game.chart);
ui_clear();
ui = initialize_ui_from_game(&game);
}
ui_end();
}

View File

@@ -1,14 +1,19 @@
CFLAGS = -std=c23 -Wextra -pedantic -Wall -pedantic
LDFLAGS = -lncurses
CFLAGS = -std=c11 -Wextra -pedantic -Wall -O0 -g3 -fsanitize=address
LDFLAGS = -lncurses -fsanitize=address
main: box.o main.o ui.o util.o
main: box.o main.o ui.o util.o chart.o
.PHONY: clean
box.o: box.c
chart.o: chart.c
main.o: main.c
ui.o: ui.c
util.o: util.c
tarball2: deel2.tar.gz
deel2.tar.gz: box.c chart.c main.c ui.c util.c box.h chart.h util.h ui.h util.h README.md makefile
tar czf $@ $^
clean:
rm *.o main
rm -f *.o main

7
ui.c
View File

@@ -22,6 +22,7 @@ ui_init(void)
init_pair(UI_BLUE, COLOR_BLUE, COLOR_BLACK);
cbreak();
noecho();
nodelay(stdscr, TRUE);
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
@@ -29,17 +30,17 @@ ui_init(void)
refresh();
}
void ui_end()
void ui_end(void)
{
endwin();
}
void ui_string(size_t x, size_t y, char *s)
void ui_string(unsigned int x, unsigned int y, char *s)
{
mvaddstr(y, x, s);
}
void ui_char(size_t x, size_t y, char c)
void ui_char(unsigned int x, unsigned int y, char c)
{
mvaddch(y, x, c);
}

4
ui.h
View File

@@ -22,8 +22,8 @@ void ui_end(void);
void ui_color_on(enum ui_color);
void ui_color_off(enum ui_color);
void ui_char(size_t x, size_t y, char c);
void ui_string(size_t x, size_t y, char *s);
void ui_char(unsigned int x, unsigned int y, char c);
void ui_string(unsigned int x, unsigned int y, char *s);
size_t ui_width(void);
size_t ui_height(void);

2
util.c
View File

@@ -23,7 +23,7 @@ emalloc(size_t n)
}
void
noreturn void
die(char *fmt, ...)
{
va_list va;

3
util.h
View File

@@ -8,7 +8,8 @@
#pragma once
#include <stddef.h>
#include <stdnoreturn.h>
void *emalloc(size_t n);
void die(char *fmt, ...);
noreturn void die(char *fmt, ...);