wm: m

Download patch

ref: cea57785283e17b1a05909860d12e9a7dfe99600
author: mkf <mkf>
date: Tue Apr 4 17:41:24 EDT 2023

import

--- /dev/null
+++ b/m.c
@@ -1,0 +1,369 @@
+/*
+note that program isn't well tested on boardx != 6, boardy != 6
+*/
+#include <stdio.h>
+
+#define boardx 6
+#define boardy 6
+#define empty ' '
+
+char board[boardx * boardy];
+int pieces[2] = { (boardx / 2 - 1)* boardy, (boardx / 2 - 1) * boardy };
+char piece[2] = { '@', '#' };
+int player = 0;
+int direction = -1;
+
+typedef struct
+{
+	int x;
+	int y;
+} point_t;
+
+typedef struct 
+{
+	point_t src;
+	point_t dst;
+} swap_t;
+
+int pindex(int, int);
+void setupboard(void);
+void showrules(void);
+void showboard(void);
+void showhelp(void);
+char check(void);
+
+int check_put(point_t);
+int check_move(point_t);
+int check_swap(swap_t);
+
+int put(point_t);
+int move(point_t);
+int swap(swap_t);
+
+typedef struct
+{
+	char act;
+	point_t pos1;
+	point_t pos2;
+} cmd_t;
+
+/* 	why y and x, and not x and y?
+ 	C does it as YX, doing it otherwise would make code
+ 	way too complex */
+int pindex(int y, int x)
+{
+	if(x < 0 || x > boardx || y < 0 || y > boardy)
+	{
+		fprintf(stderr, "pindex(%d, %d) out of range\n", x, y);
+		return -1;
+	}
+	return (x * boardy) + y;
+}
+
+
+void setupboard(void)
+{
+	for(int x = 0; x < boardx; x++)
+	{
+		for(int y = 0; y < boardy; y++)
+		{
+			if(x == 0)
+				board[pindex(x, y)] = piece[1];
+			else if(x == boardx - 1)
+				board[pindex(x, y)] = piece[0];
+			else 
+				board[pindex(x, y)] = empty;
+		}
+	}
+}
+
+
+void showboard(void)
+{
+	printf("\n");
+	printf("free %c: %d, free %c: %d\n", piece[0], pieces[0], piece[1], pieces[1]);
+	for(int i = -1; i < boardx; i++)
+	{
+		if(i != -1) // makes top most sqaure ugly
+			printf(" %d |", i);
+		else
+			printf(" * |");
+		for(int j = 0; j < boardy; j++)
+		{
+			if(i == -1)
+				printf(" %d |", j);
+			else
+				printf(" %c |", board[pindex(i, j)]);
+		}
+		printf("\n");
+	}
+}
+
+void showrules(void)
+{
+	printf("The goal is make a 4 in a row, where\n"
+		"at least half (2) of them are other side.\n"
+		"commands:\n"
+		"h: show this help, b: show board, #: comment, NOP \n"
+		"pXY: put a piece on XY, you may only do it for your first two rows.\n"
+		"mXY: move the piece on XY one square forward.\n"
+		"sXYXY: swap first two pieces, only if they are adjecnet.\n");
+}
+
+void chplayer(void)
+{
+	player = !player;
+	direction *= -1;
+}
+
+cmd_t getcmd(void)
+{
+	char string[6];
+	point_t pos1, pos2;
+	cmd_t cmd;
+	printf("\n%c turn> ", piece[player]);
+	scanf("%s", string);
+	switch(string[0])
+	{
+		case 'm':
+		case 'p':
+			sscanf(&string[1], "%1d%1d", &pos1.x, &pos1.y);
+			cmd.pos1 = pos1;
+			break;
+
+		case 's':
+			sscanf(&string[1],"%1d%1d%1d%1d", &pos1.x, &pos1.y, &pos2.x, &pos2.y);
+			cmd.pos1 = pos1;
+			cmd.pos2 = pos2;
+			break;
+	}
+	cmd.act = string[0];
+	return cmd;
+}
+
+int proccmd(cmd_t cmd)
+{
+	switch(cmd.act)
+	{
+		case 'm':
+		{
+			if(pindex(cmd.pos1.x, cmd.pos1.y) == -1)
+				return -1;
+			return move(cmd.pos1);
+		}
+
+		case 's':
+		{
+			if(pindex(cmd.pos1.x, cmd.pos1.y) == -1
+			|| pindex(cmd.pos2.x, cmd.pos2.y) == -1)
+				return -1;
+			swap_t s;
+			s.src = cmd.pos1;
+			s.dst = cmd.pos2;
+			return swap(s);
+		}
+
+		case 'p':
+		{
+			if(pindex(cmd.pos1.x, cmd.pos1.y) == -1)
+				return -1;
+			return put(cmd.pos1);
+		}
+
+		case 'b':
+		{
+			showboard();
+			break;
+		}
+
+		case 'h':
+		{
+			showrules();
+			break;
+		}
+		case '#':
+		{
+			break;
+		}
+		default:
+		{
+			fprintf(stderr, "unkown command.\n");
+			break;
+		}
+	}
+	return -1;	
+}
+
+char check(void)
+{
+	for(int x = 0 ; x < boardx ; x++)
+	{
+		for(int y = 0 ; y < boardy - 3 ; y++)
+		{
+			if(board[pindex(x, y)] != empty)
+			{
+				// horzictal
+				if((board[pindex(x, y)] == piece[0] && x < (boardx / 2 + 1))
+				|| (board[pindex(x, y)] == piece[1] && x >= (boardx / 2)))
+					if(board[pindex(x, y)] == board[pindex(x, y+1)]
+					&& board[pindex(x, y)] == board[pindex(x, y+2)]
+					&& board[pindex(x, y)] == board[pindex(x, y+3)])
+					{
+						printf("deb\n");
+						return board[pindex(x, y)];
+					}
+				// vertical
+				if((player == 0 && x < ( boardx / 2 + 1 ))
+				|| (player == 1 && x >= ( boardx / 2 + 1)))
+					if(board[pindex(x, y)] == board[pindex(x - direction, y)] 
+					&& board[pindex(x, y)] == board[pindex(x - direction * 2, y)]
+					&& board[pindex(x, y)] == board[pindex(x - direction * 3, y)])
+						return board[pindex(x, y)];
+
+				// diagonal rtl
+				if(y == 1 || y == 2)
+					if(board[pindex(x, y)] == board[pindex(x+1, y+1)] 
+					&& board[pindex(x, y)] == board[pindex(x+2, y+2)]
+					&& board[pindex(x, y)] == board[pindex(x+3, y+3)])
+						return board[pindex(x, y)];
+
+				// diagonal ltr
+				if(y == 3 || y == 4)
+					if(board[pindex(x, y)] == board[pindex(x+1, y-1)] 
+					&& board[pindex(x, y)] == board[pindex(x+2, y-2)]
+					&& board[pindex(x, y)] == board[pindex(x+3, y-3)])
+						return board[pindex(x, y)];
+			}
+		}
+	}
+	return empty;	
+}
+
+int check_swap(swap_t swap)
+{
+	if((pindex(swap.src.x, swap.src.y) < 0)
+	|| (pindex(swap.dst.x, swap.dst.y) < 0))
+	{
+		fprintf(stderr, "invalid input\n");
+		return -1;
+	}
+
+	if(swap.src.x - swap.dst.x > 1
+	|| swap.src.x - swap.dst.x < -1
+	|| swap.src.y - swap.dst.y > 1
+	|| swap.src.y - swap.dst.y < -1)
+	{
+		fprintf(stderr, "src and dst aren't adjecent\n");
+		return -2;
+	}
+
+	if(board[pindex(swap.src.x, swap.src.y)] == empty
+	|| board[pindex(swap.dst.x, swap.dst.y)] == empty)
+	{
+		fprintf(stderr, "src or dst is empty\n");
+		return -3;
+	}
+
+	if(board[pindex(swap.src.x, swap.src.y)]
+	== board[pindex(swap.dst.x, swap.dst.y)])
+	{
+		fprintf(stderr, "src and dst have the same piece\n");
+		return -4;
+	}
+	
+	if(pindex(swap.src.x, swap.src.y)
+	== pindex(swap.dst.x, swap.dst.y))
+	{
+		fprintf(stderr, "src and dst are the same square\n");
+		return -5;
+	}
+
+	return 0;
+}
+
+int swap(swap_t swap)
+{
+	if(check_swap(swap) < 0)
+		return -1;
+	char temp = board[pindex(swap.src.x, swap.src.y)];
+	board[pindex(swap.src.x, swap.src.y)] = board[pindex(swap.dst.x, swap.dst.y)];
+	board[pindex(swap.dst.x, swap.dst.y)] = temp;
+	return 0;
+}
+
+int check_move(point_t point) // todo: add checks for last row
+{
+	if(pindex(point.x, point.y) == -1)
+	{
+		fprintf(stderr, "invalid input\n");
+		return -1;
+	}
+
+	if(board[pindex(point.x, point.y)] != piece[player])
+	{
+		fprintf(stderr, "src is not your piece\n");
+		return -2;
+	}
+
+	if(board[pindex(point.x + direction, point.y )] != empty)
+	{
+		fprintf(stderr, "dst is not empty\n");
+		return -3;
+	}
+	return 0;
+}
+
+int move(point_t point)
+{
+	if(check_move(point) < 0)
+		return -1;
+	board[pindex(point.x + direction, point.y)] = piece[player];
+	board[pindex(point.x, point.y)] = empty;
+	return 0;
+}
+
+int check_put(point_t point)
+{
+	if(pindex(point.x, point.y) == -1)
+	{
+		fprintf(stderr, "invalid input\n");
+		return -1;
+	}
+	if(board[pindex(point.x, point.y)] != empty)
+	{
+		fprintf(stderr, "dst is not empty\n");
+		return -2;
+	}
+	if((player == 0 && point.x < 4)
+	|| (player == 1 && point.x > 1))
+	{
+		fprintf(stderr, "it's not on your first two rows\n");
+		return -3;
+	}
+	return 0;
+}
+
+int put(point_t point)
+{
+	if(check_put(point) < 0)
+		return -1;
+	board[pindex(point.x, point.y)] = piece[player];
+	pieces[player]--;
+	return 0;
+}
+
+int main(void)
+{
+	showrules();
+	setupboard();
+	showboard();
+	while(check() == empty)
+	{
+		if(proccmd(getcmd()) == 0)
+		{
+			chplayer();
+			showboard();
+		}
+	}
+	return 0;
+}