summary refs log tree commit diff
path: root/bin/klon.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/klon.c')
-rw-r--r--bin/klon.c484
1 files changed, 242 insertions, 242 deletions
diff --git a/bin/klon.c b/bin/klon.c
index 9d82d88c..878f7f6d 100644
--- a/bin/klon.c
+++ b/bin/klon.c
@@ -26,334 +26,334 @@
 typedef uint8_t Card;
 
 enum {
-    MASK_RANK   = 0x0F,
-    MASK_SUIT   = 0x30,
-    MASK_COLOR  = 0x10,
-    MASK_UP     = 0x40,
-    MASK_SELECT = 0x80,
+	MASK_RANK   = 0x0F,
+	MASK_SUIT   = 0x30,
+	MASK_COLOR  = 0x10,
+	MASK_UP     = 0x40,
+	MASK_SELECT = 0x80,
 };
 
 enum {
-    SUIT_CLUB    = 0x00,
-    SUIT_DIAMOND = 0x10,
-    SUIT_SPADE   = 0x20,
-    SUIT_HEART   = 0x30,
+	SUIT_CLUB    = 0x00,
+	SUIT_DIAMOND = 0x10,
+	SUIT_SPADE   = 0x20,
+	SUIT_HEART   = 0x30,
 };
 
 struct Stack {
-    Card data[52];
-    uint8_t index;
+	Card data[52];
+	uint8_t index;
 };
 #define EMPTY { .data = {0}, .index = 52 }
 
 static void push(struct Stack *stack, Card card) {
-    assert(stack->index > 0);
-    stack->data[--stack->index] = card;
+	assert(stack->index > 0);
+	stack->data[--stack->index] = card;
 }
 
 static Card pop(struct Stack *stack) {
-    assert(stack->index < 52);
-    return stack->data[stack->index++];
+	assert(stack->index < 52);
+	return stack->data[stack->index++];
 }
 
 static Card get(const struct Stack *stack, uint8_t i) {
-    if (stack->index + i > 51) return 0;
-    return stack->data[stack->index + i];
+	if (stack->index + i > 51) return 0;
+	return stack->data[stack->index + i];
 }
 
 static uint8_t len(const struct Stack *stack) {
-    return 52 - stack->index;
+	return 52 - stack->index;
 }
 
 struct State {
-    struct Stack stock;
-    struct Stack waste;
-    struct Stack found[4];
-    struct Stack table[7];
+	struct Stack stock;
+	struct Stack waste;
+	struct Stack found[4];
+	struct Stack table[7];
 };
 
 static struct State g = {
-    .stock = {
-        .data = {
-            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
-            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-            0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
-            0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-            0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
-        },
-        .index = 0,
-    },
-    .waste = EMPTY,
-    .found = { EMPTY, EMPTY, EMPTY, EMPTY },
-    .table = {
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
-    },
+	.stock = {
+		.data = {
+			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
+			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+			0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
+			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+			0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
+		},
+		.index = 0,
+	},
+	.waste = EMPTY,
+	.found = { EMPTY, EMPTY, EMPTY, EMPTY },
+	.table = {
+		EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
+	},
 };
 
 static struct State save;
 
 static void checkpoint(void) {
-    memcpy(&save, &g, sizeof(struct State));
+	memcpy(&save, &g, sizeof(struct State));
 }
 
 static void undo(void) {
-    memcpy(&g, &save, sizeof(struct State));
+	memcpy(&g, &save, sizeof(struct State));
 }
 
 static void shuffle(void) {
-    for (int i = 51; i > 0; --i) {
-        int j = arc4random_uniform(i + 1);
-        uint8_t x = g.stock.data[i];
-        g.stock.data[i] = g.stock.data[j];
-        g.stock.data[j] = x;
-    }
+	for (int i = 51; i > 0; --i) {
+		int j = arc4random_uniform(i + 1);
+		uint8_t x = g.stock.data[i];
+		g.stock.data[i] = g.stock.data[j];
+		g.stock.data[j] = x;
+	}
 }
 
 static void deal(void) {
-    for (int i = 0; i < 7; ++i) {
-        for (int j = i; j < 7; ++j) {
-            push(&g.table[j], pop(&g.stock));
-        }
-    }
+	for (int i = 0; i < 7; ++i) {
+		for (int j = i; j < 7; ++j) {
+			push(&g.table[j], pop(&g.stock));
+		}
+	}
 }
 
 static void reveal(void) {
-    for (int i = 0; i < 7; ++i) {
-        if (get(&g.table[i], 0)) {
-            push(&g.table[i], pop(&g.table[i]) | MASK_UP);
-        }
-    }
+	for (int i = 0; i < 7; ++i) {
+		if (get(&g.table[i], 0)) {
+			push(&g.table[i], pop(&g.table[i]) | MASK_UP);
+		}
+	}
 }
 
 static void draw(void) {
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
 }
 
 static void wasted(void) {
-    uint8_t n = len(&g.waste);
-    for (int i = 0; i < n; ++i) {
-        push(&g.stock, pop(&g.waste) & ~MASK_UP);
-    }
+	uint8_t n = len(&g.waste);
+	for (int i = 0; i < n; ++i) {
+		push(&g.stock, pop(&g.waste) & ~MASK_UP);
+	}
 }
 
 static void transfer(struct Stack *dest, struct Stack *src, uint8_t n) {
-    struct Stack temp = EMPTY;
-    for (int i = 0; i < n; ++i) {
-        push(&temp, pop(src));
-    }
-    for (int i = 0; i < n; ++i) {
-        push(dest, pop(&temp));
-    }
+	struct Stack temp = EMPTY;
+	for (int i = 0; i < n; ++i) {
+		push(&temp, pop(src));
+	}
+	for (int i = 0; i < n; ++i) {
+		push(dest, pop(&temp));
+	}
 }
 
 static bool canFound(const struct Stack *found, Card card) {
-    if (!get(found, 0)) return (card & MASK_RANK) == 1;
-    if ((card & MASK_SUIT) != (get(found, 0) & MASK_SUIT)) return false;
-    return (card & MASK_RANK) == (get(found, 0) & MASK_RANK) + 1;
+	if (!get(found, 0)) return (card & MASK_RANK) == 1;
+	if ((card & MASK_SUIT) != (get(found, 0) & MASK_SUIT)) return false;
+	return (card & MASK_RANK) == (get(found, 0) & MASK_RANK) + 1;
 }
 
 static bool canTable(const struct Stack *table, Card card) {
-    if (!get(table, 0)) return (card & MASK_RANK) == 13;
-    if ((card & MASK_COLOR) == (get(table, 0) & MASK_COLOR)) return false;
-    return (card & MASK_RANK) == (get(table, 0) & MASK_RANK) - 1;
+	if (!get(table, 0)) return (card & MASK_RANK) == 13;
+	if ((card & MASK_COLOR) == (get(table, 0) & MASK_COLOR)) return false;
+	return (card & MASK_RANK) == (get(table, 0) & MASK_RANK) - 1;
 }
 
 enum {
-    PAIR_EMPTY = 1,
-    PAIR_BACK,
-    PAIR_BLACK,
-    PAIR_RED,
+	PAIR_EMPTY = 1,
+	PAIR_BACK,
+	PAIR_BLACK,
+	PAIR_RED,
 };
 
 static void curse(void) {
-    setlocale(LC_CTYPE, "");
-
-    initscr();
-    cbreak();
-    noecho();
-    keypad(stdscr, true);
-    set_escdelay(100);
-    curs_set(0);
-
-    start_color();
-    assume_default_colors(-1, -1);
-    init_pair(PAIR_EMPTY, COLOR_WHITE, COLOR_BLACK);
-    init_pair(PAIR_BACK,  COLOR_WHITE, COLOR_BLUE);
-    init_pair(PAIR_BLACK, COLOR_BLACK, COLOR_WHITE);
-    init_pair(PAIR_RED,   COLOR_RED,   COLOR_WHITE);
+	setlocale(LC_CTYPE, "");
+
+	initscr();
+	cbreak();
+	noecho();
+	keypad(stdscr, true);
+	set_escdelay(100);
+	curs_set(0);
+
+	start_color();
+	assume_default_colors(-1, -1);
+	init_pair(PAIR_EMPTY, COLOR_WHITE, COLOR_BLACK);
+	init_pair(PAIR_BACK,  COLOR_WHITE, COLOR_BLUE);
+	init_pair(PAIR_BLACK, COLOR_BLACK, COLOR_WHITE);
+	init_pair(PAIR_RED,   COLOR_RED,   COLOR_WHITE);
 }
 
 static const char rank[] = "\0A23456789TJQK";
 static const char *suit[] = {
-    [SUIT_HEART]   = "♥",
-    [SUIT_CLUB]    = "♣",
-    [SUIT_DIAMOND] = "♦",
-    [SUIT_SPADE]   = "♠",
+	[SUIT_HEART]   = "♥",
+	[SUIT_CLUB]    = "♣",
+	[SUIT_DIAMOND] = "♦",
+	[SUIT_SPADE]   = "♠",
 };
 
 static void renderCard(int y, int x, Card card) {
-    if (card & MASK_UP) {
-        bkgdset(
-            COLOR_PAIR(card & MASK_COLOR ? PAIR_RED : PAIR_BLACK)
-            | (card & MASK_SELECT ? A_REVERSE : A_NORMAL)
-        );
-
-        move(y, x);
-        addch(rank[card & MASK_RANK]);
-        addstr(suit[card & MASK_SUIT]);
-        addch(' ');
-
-        move(y + 1, x);
-        addstr(suit[card & MASK_SUIT]);
-        addch(' ');
-        addstr(suit[card & MASK_SUIT]);
-
-        move(y + 2, x);
-        addch(' ');
-        addstr(suit[card & MASK_SUIT]);
-        addch(rank[card & MASK_RANK]);
-
-    } else {
-        bkgdset(COLOR_PAIR(card ? PAIR_BACK : PAIR_EMPTY));
-        mvaddstr(y, x, "   ");
-        mvaddstr(y + 1, x, "   ");
-        mvaddstr(y + 2, x, "   ");
-    }
+	if (card & MASK_UP) {
+		bkgdset(
+			COLOR_PAIR(card & MASK_COLOR ? PAIR_RED : PAIR_BLACK)
+			| (card & MASK_SELECT ? A_REVERSE : A_NORMAL)
+		);
+
+		move(y, x);
+		addch(rank[card & MASK_RANK]);
+		addstr(suit[card & MASK_SUIT]);
+		addch(' ');
+
+		move(y + 1, x);
+		addstr(suit[card & MASK_SUIT]);
+		addch(' ');
+		addstr(suit[card & MASK_SUIT]);
+
+		move(y + 2, x);
+		addch(' ');
+		addstr(suit[card & MASK_SUIT]);
+		addch(rank[card & MASK_RANK]);
+
+	} else {
+		bkgdset(COLOR_PAIR(card ? PAIR_BACK : PAIR_EMPTY));
+		mvaddstr(y, x, "   ");
+		mvaddstr(y + 1, x, "   ");
+		mvaddstr(y + 2, x, "   ");
+	}
 }
 
 static void render(void) {
-    bkgdset(COLOR_PAIR(0));
-    erase();
-
-    int x = 2;
-    int y = 1;
-
-    renderCard(y, x, get(&g.stock, 0));
-
-    x += 5;
-    renderCard(y, x++, get(&g.waste, 2));
-    renderCard(y, x++, get(&g.waste, 1));
-    renderCard(y, x, get(&g.waste, 0));
-
-    x += 5;
-    for (int i = 0; i < 4; ++i) {
-        renderCard(y, x, get(&g.found[i], 0));
-        x += 4;
-    }
-
-    x = 2;
-    for (int i = 0; i < 7; ++i) {
-        y = 5;
-        renderCard(y, x, 0);
-        for (int j = len(&g.table[i]); j > 0; --j) {
-            renderCard(y, x, get(&g.table[i], j - 1));
-            y++;
-        }
-        x += 4;
-    }
+	bkgdset(COLOR_PAIR(0));
+	erase();
+
+	int x = 2;
+	int y = 1;
+
+	renderCard(y, x, get(&g.stock, 0));
+
+	x += 5;
+	renderCard(y, x++, get(&g.waste, 2));
+	renderCard(y, x++, get(&g.waste, 1));
+	renderCard(y, x, get(&g.waste, 0));
+
+	x += 5;
+	for (int i = 0; i < 4; ++i) {
+		renderCard(y, x, get(&g.found[i], 0));
+		x += 4;
+	}
+
+	x = 2;
+	for (int i = 0; i < 7; ++i) {
+		y = 5;
+		renderCard(y, x, 0);
+		for (int j = len(&g.table[i]); j > 0; --j) {
+			renderCard(y, x, get(&g.table[i], j - 1));
+			y++;
+		}
+		x += 4;
+	}
 }
 
 static struct {
-    struct Stack *stack;
-    uint8_t depth;
+	struct Stack *stack;
+	uint8_t depth;
 } input;
 
 static void deepen(void) {
-    assert(input.stack);
-    if (input.depth == len(input.stack)) return;
-    if (!(get(input.stack, input.depth) & MASK_UP)) return;
-    input.stack->data[input.stack->index + input.depth] |= MASK_SELECT;
-    input.depth++;
+	assert(input.stack);
+	if (input.depth == len(input.stack)) return;
+	if (!(get(input.stack, input.depth) & MASK_UP)) return;
+	input.stack->data[input.stack->index + input.depth] |= MASK_SELECT;
+	input.depth++;
 }
 
 static void select(struct Stack *stack) {
-    if (!get(stack, 0)) return;
-    input.stack = stack;
-    input.depth = 0;
-    deepen();
+	if (!get(stack, 0)) return;
+	input.stack = stack;
+	input.depth = 0;
+	deepen();
 }
 
 static void commit(struct Stack *dest) {
-    assert(input.stack);
-    for (int i = 0; i < input.depth; ++i) {
-        input.stack->data[input.stack->index + i] &= ~MASK_SELECT;
-    }
-    if (dest) {
-        checkpoint();
-        transfer(dest, input.stack, input.depth);
-    }
-    input.stack = NULL;
-    input.depth = 0;
+	assert(input.stack);
+	for (int i = 0; i < input.depth; ++i) {
+		input.stack->data[input.stack->index + i] &= ~MASK_SELECT;
+	}
+	if (dest) {
+		checkpoint();
+		transfer(dest, input.stack, input.depth);
+	}
+	input.stack = NULL;
+	input.depth = 0;
 }
 
 int main() {
-    curse();
-
-    shuffle();
-    deal();
-    checkpoint();
-
-    for (;;) {
-        reveal();
-        render();
-
-        int c = getch();
-        if (!input.stack) {
-            if (c == 'q') {
-                break;
-            } else if (c == 'u') {
-                undo();
-            } else if (c == 's' || c == ' ') {
-                if (get(&g.stock, 0)) {
-                    checkpoint();
-                    draw();
-                } else {
-                    wasted();
-                }
-            } else if (c == 'w') {
-                select(&g.waste);
-            } else if (c >= 'a' && c <= 'd') {
-                select(&g.found[c - 'a']);
-            } else if (c >= '1' && c <= '7') {
-                select(&g.table[c - '1']);
-            }
-
-        } else {
-            if (c >= '1' && c <= '7') {
-                struct Stack *table = &g.table[c - '1'];
-                if (input.stack == table) {
-                    deepen();
-                } else if (canTable(table, get(input.stack, input.depth - 1))) {
-                    commit(table);
-                } else {
-                    commit(NULL);
-                }
-            } else if (input.depth == 1 && c >= 'a' && c <= 'd') {
-                struct Stack *found = &g.found[c - 'a'];
-                if (canFound(found, get(input.stack, 0))) {
-                    commit(found);
-                } else {
-                    commit(NULL);
-                }
-            } else if (input.depth == 1 && (c == 'f' || c == '\n')) {
-                struct Stack *found;
-                for (int i = 0; i < 4; ++i) {
-                    found = &g.found[i];
-                    if (canFound(found, get(input.stack, 0))) break;
-                    found = NULL;
-                }
-                commit(found);
-            } else {
-                commit(NULL);
-            }
-        }
-    }
-
-    endwin();
-    return 0;
+	curse();
+
+	shuffle();
+	deal();
+	checkpoint();
+
+	for (;;) {
+		reveal();
+		render();
+
+		int c = getch();
+		if (!input.stack) {
+			if (c == 'q') {
+				break;
+			} else if (c == 'u') {
+				undo();
+			} else if (c == 's' || c == ' ') {
+				if (get(&g.stock, 0)) {
+					checkpoint();
+					draw();
+				} else {
+					wasted();
+				}
+			} else if (c == 'w') {
+				select(&g.waste);
+			} else if (c >= 'a' && c <= 'd') {
+				select(&g.found[c - 'a']);
+			} else if (c >= '1' && c <= '7') {
+				select(&g.table[c - '1']);
+			}
+
+		} else {
+			if (c >= '1' && c <= '7') {
+				struct Stack *table = &g.table[c - '1'];
+				if (input.stack == table) {
+					deepen();
+				} else if (canTable(table, get(input.stack, input.depth - 1))) {
+					commit(table);
+				} else {
+					commit(NULL);
+				}
+			} else if (input.depth == 1 && c >= 'a' && c <= 'd') {
+				struct Stack *found = &g.found[c - 'a'];
+				if (canFound(found, get(input.stack, 0))) {
+					commit(found);
+				} else {
+					commit(NULL);
+				}
+			} else if (input.depth == 1 && (c == 'f' || c == '\n')) {
+				struct Stack *found;
+				for (int i = 0; i < 4; ++i) {
+					found = &g.found[i];
+					if (canFound(found, get(input.stack, 0))) break;
+					found = NULL;
+				}
+				commit(found);
+			} else {
+				commit(NULL);
+			}
+		}
+	}
+
+	endwin();
+	return 0;
 }