shithub: city

Download patch

ref: 24e3f38bb4e102aebca99a107ccbe99dbf4a107f
author: qwx <qwx@sciops.net>
date: Sun Feb 14 17:41:03 EST 2021

skeleton

--- /dev/null
+++ b/city.c
@@ -1,0 +1,50 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+int tdiv;
+vlong clock;
+
+void *
+emalloc(ulong n)
+{
+	void *p;
+
+	if((p = mallocz(n, 1)) == nil)
+		sysfatal("emalloc: %r");
+	setmalloctag(p, getcallerpc(&n));
+	return p;
+}
+
+void
+input(void)
+{
+
+}
+
+void
+main(int argc, char **argv)
+{
+	vlong t, t0, dt, Δtc;
+
+	ARGBEGIN{
+	}ARGEND
+	srand(time(nil));
+	init();
+	tdiv = Te9 / THz;
+	t0 = nsec();
+	for(;;){
+		input();
+		step();
+		clock++;
+		t = nsec();
+		Δtc = (t - t0) / tdiv;
+		if(Δtc <= 0)
+			Δtc = 1;
+		t0 += Δtc * tdiv;
+		dt = (t0 - t) / Te6;
+		if(dt > 0)
+			sleep(dt);
+	}
+}
--- /dev/null
+++ b/dat.h
@@ -1,0 +1,110 @@
+typedef struct Resource Resource;
+typedef struct Good Good;
+typedef struct Building Building;
+typedef struct Terrain Terrain;
+typedef struct Tile Tile;
+
+enum{
+	Gfish,
+	Gcattle,
+	Gwheat,
+	Gwood,
+	Glumber,
+	Gstone,
+	Giron,
+	Gtools,
+	Ggold,
+	Gjewelry,
+	Gtot,
+};
+struct Good{
+	char *name;
+	int terrain;
+	int resource;
+};
+extern Good goods[Gtot];
+extern int initialstock[Gtot];
+
+enum{
+	Rfood,
+	Rwood,
+	Rlumber,
+	Rstone,
+	Riron,
+	Rtools,
+	Rgold,
+	Rjewelry,
+	Rtot,
+};
+struct Resource{
+	char *name;
+	int goods[Gtot];
+};
+
+enum{
+	Btownhall,
+	Bmarket,
+	Bfishyard,
+	Bcarpentry,
+	Bsawmill,
+	Bmill,
+	Bfarm,
+	Bquarry,
+	Bsmeltery,
+	Bforge,
+	Blapidary,
+	Btot,
+};
+struct Building{
+	char *name;
+	int time;
+	int buildtime;
+	int costs[Gtot];
+	int terrain;
+	int goods[Gtot];
+	int upkeep[Rtot];
+};
+extern Building buildings[Btot];
+
+enum{
+	Tplain,
+	Twoods,
+	Tpond,
+	Tcrop,
+	Tmountain,
+	Tironvein,
+	Tgoldvein,
+	Ttot,
+};
+struct Terrain{
+	char *name;
+	int good;
+	int initialstock;
+	double yield;
+};
+extern Terrain terrains[Ttot];
+
+enum{
+	Snull,
+	Swait,
+	Sbuild,
+	Sproduce,
+};
+struct Tile{
+	Terrain *t;
+	Building *b;
+	int stock;
+	int state;
+	int clock;
+};
+extern Tile *map;
+extern int mapwidth, mapheight;
+
+enum{
+	Te9 = 1000000000,
+	Te6 = 1000000,
+	THz = 5,
+	Travelticks = 10,
+};
+extern int tdiv;
+extern vlong clock;
--- /dev/null
+++ b/defs.c
@@ -1,0 +1,308 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+
+Good goods[] = {
+	[Gfish]{
+		.name "fish",
+		.terrain Tpond,
+		.resource Rfood,
+	},[Gcattle]{
+		.name "cattle",
+		.terrain -1,
+		.resource Rfood,
+	},[Gwheat]{
+		.name "wheat",
+		.terrain -1,
+		.resource Rfood,
+	},[Gwood]{
+		.name "wood",
+		.terrain Twoods,
+		.resource Rwood,
+	},[Glumber]{
+		.name "lumber",
+		.terrain -1,
+		.resource Rlumber,
+	},[Gstone]{
+		.name "stone",
+		.terrain Tmountain,
+		.resource Rstone,
+	},[Giron]{
+		.name "iron",
+		.terrain -1,
+		.resource Riron,
+	},[Gtools]{
+		.name "tools",
+		.terrain -1,
+		.resource Rtools,
+	},[Ggold]{
+		.name "gold",
+		.terrain Tgoldvein,
+		.resource Rgold,
+	},[Gjewelry]{
+		.name "jewelry",
+		.terrain -1,
+		.resource Rjewelry,
+	}
+};
+int initialstock[Gtot] = {
+	[Gwood] 10,
+	[Gwheat] 5,
+	[Gfish] 5,
+	[Gcattle] 5,
+	[Ggold] 100,
+};
+Resource resources[] = {
+	[Rfood]{
+		.name "food",
+		.goods {
+			[Gfish] 1,
+			[Gcattle] 1,
+			[Gwheat] 1,
+		},
+	},[Rwood]{
+		.name "wood",
+		.goods {
+			[Gwood] 1,
+		},
+	},[Rlumber]{
+		.name "lumber",
+		.goods {
+			[Glumber] 1,
+		},
+	},[Rstone]{
+		.name "stone",
+		.goods {
+			[Gstone] 1,
+		},
+	},[Riron]{
+		.name "iron",
+		.goods {
+			[Giron] 1,
+		},
+	},[Rtools]{
+		.name "tools",
+		.goods {
+			[Gtools] 1,
+		},
+	},[Rgold]{
+		.name "gold",
+		.goods {
+			[Ggold] 1,
+		},
+	},[Rjewelry]{
+		.name "jewelry",
+		.goods {
+			[Gjewelry] 1,
+		},
+	}
+};
+Building buildings[] = {
+	[Btownhall]{
+		.name "townhall",
+		.time 0,
+		.buildtime 1000,
+		.costs {0},
+		.terrain Tplain,
+		.goods {0},
+		.upkeep {
+			[Rfood] 1,
+		},
+	},[Bcarpentry]{
+		.name "carpentry",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 3,
+			[Gwood] 3,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gwood] 1,
+		},
+		.upkeep {
+			[Rfood] 1,
+		},
+	},[Bsawmill]{
+		.name "sawmill",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 10,
+			[Gwood] 10,
+		},
+		.terrain Tplain,
+		.goods {
+			[Glumber] 1,
+		},
+		.upkeep {
+			[Rfood] 2,
+		},
+	},[Bfishyard]{
+		.name "fishyard",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 5,
+			[Gwood] 5,
+		},
+		.terrain Tpond,
+		.goods {
+			[Gfish] 1,
+		},
+		.upkeep {
+			[Rfood] 1,
+		},
+	},[Bmill]{
+		.name "mill",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 8,
+			[Glumber] 8,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gwheat] 2,
+		},
+		.upkeep {
+			[Rfood] 1,
+		},
+	},[Bfarm]{
+		.name "farm",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 8,
+			[Glumber] 4,
+			[Gwheat] 4,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gcattle] 2,
+		},
+		.upkeep {
+			[Rfood] 1,
+			[Rlumber] 1,
+		},
+	},[Bquarry]{
+		.name "quarry",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 5,
+			[Glumber] 2,
+			[Gwheat] 3,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gstone] 1,
+		},
+		.upkeep {
+			[Rfood] 1,
+		},
+	},[Bsmeltery]{
+		.name "smeltery",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 12,
+			[Glumber] 6,
+			[Gstone] 4,
+			[Gwood] 2,
+		},
+		.terrain Tplain,
+		.goods {
+			[Giron] 1,
+		},
+		.upkeep {
+			[Rfood] 2,
+		},
+	},[Bforge]{
+		.name "forge",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 10,
+			[Glumber] 4,
+			[Gstone] 4,
+			[Giron] 2,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gtools] 1,
+		},
+		.upkeep {
+			[Rfood] 2,
+		},
+	},[Blapidary]{
+		.name "lapidary",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 26,
+			[Gstone] 16,
+			[Giron] 14,
+			[Gtools] 14,
+		},
+		.terrain Tplain,
+		.goods {
+			[Gjewelry] 1,
+		},
+		.upkeep {
+			[Rfood] 2,
+		},
+	},[Bmarket]{
+		.name "market",
+		.time 25,
+		.buildtime 50,
+		.costs {
+			[Ggold] 10,
+			[Glumber] 10,
+		},
+		.terrain Tplain,
+		.goods {0},
+		.upkeep {
+			[Rgold] 1,
+			[Rfood] 5,
+		},
+	}
+};
+Terrain terrains[] = {
+	[Tplain]{
+		.name "plain",
+		.good -1,
+		.initialstock 0,
+		.yield 0,
+	},[Twoods]{
+		.name "woods",
+		.good Gwood,
+		.initialstock 9001,
+		.yield 1,
+	},[Tpond]{
+		.name "pond",
+		.good Gfish,
+		.initialstock 9001,
+		.yield 1,
+	},[Tcrop]{
+		.name "crop",
+		.good Gwheat,
+		.initialstock 800,
+		.yield 0.8,
+	},[Tmountain]{
+		.name "mountain",
+		.good Gstone,
+		.initialstock 9001,
+		.yield 0.8,
+	},[Tironvein]{
+		.name "ironvein",
+		.good Giron,
+		.initialstock 9001,
+		.yield 0.5,
+	},[Tgoldvein]{
+		.name "goldvein",
+		.good Ggold,
+		.initialstock 9001,
+		.yield 0.3,
+	},
+};
--- /dev/null
+++ b/drw.c
@@ -1,0 +1,4 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
--- /dev/null
+++ b/fns.h
@@ -1,0 +1,5 @@
+void*	emalloc(ulong);
+void	init(void);
+void	initmap(void);
+void	step(void);
+void	input(void);
--- /dev/null
+++ b/map.c
@@ -1,0 +1,30 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+int mapwidth, mapheight;
+Tile *map;
+
+void
+loadmap(void)
+{
+	Tile *m;
+	Terrain *t;
+
+	for(m=map; m<map+mapwidth*mapheight; m++){
+		t = terrains + nrand(Ttot);
+		m->t = t;
+		m->state = Snull;
+		m->stock = t->initialstock;
+	}
+}
+
+void
+initmap(void)
+{
+	mapwidth = 16;
+	mapheight = 16;
+	map = emalloc(mapwidth * mapheight * sizeof *map);
+	loadmap();
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,11 @@
+</$objtype/mkfile
+BIN=$home/bin/$objtype
+TARG=city
+OFILES=\
+	city.$O\
+	defs.$O\
+	map.$O\
+	sim.$O\
+
+HFILES=dat.h fns.h
+</sys/src/cmd/mkone
--- /dev/null
+++ b/sim.c
@@ -1,0 +1,100 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+static Tile **objs, **objhead;
+static int maxobj;
+
+enum{
+	UpkeepΔt = 150,
+};
+static int stock[Gtot], rstock[Rtot];
+
+static void
+spawn(Tile *m, int n)
+{
+	Tile **o;
+
+	if(objhead - objs >= maxobj)
+		sysfatal("spawn: out of bounds");
+	m->t = terrains + Tplain;
+	m->b = buildings + n;
+	for(o=objhead-1; o>=objs; o--)
+		if((*o)->b - buildings <= n)
+			break;
+	/* push in front of lower priority object */
+	if(++o < objhead)
+		memmove(o+1, o, (objhead - o) * sizeof *o);
+	*o = m;
+	objhead++;
+}
+
+static void
+upkeep(void)
+{
+	Tile **o;
+
+	if(clock % UpkeepΔt != 0 || clock == 0)
+		return;
+	for(o=objhead-1; o>=objs; o--){
+		/* if upkeep can't be kept, stop production immediately
+		 * else decrease stock
+		 */
+	}
+}
+
+static void
+updateobj(void)
+{
+/*
+	iterate through obj stack
+
+	build
+		call for supplies, start travel towards building site
+		done?
+		start production
+	upgrade
+		finished?
+		start production
+	destroy
+		finished?
+		despawn
+	produce
+		call for supplies
+		enough supplies? else wait until next tick (loop)
+		decrement stocks, start traveling from townhall
+		reached building?
+		increment supplies
+		begin production
+		while producing, if we can call for supplies earlier to restart immediately, do it
+		finished producing?
+		start travel towards building
+		reached building?
+		call for pickup
+		loop
+*/
+}
+
+void
+step(void)
+{
+	upkeep();
+	updateobj();
+}
+
+void
+init(void)
+{
+	int i;
+
+	initmap();
+	maxobj = mapwidth * mapheight;
+	objs = emalloc(maxobj * sizeof *objs);
+	objhead = objs;
+	spawn(map + nrand(maxobj), Btownhall);
+	for(i=0; i<nelem(initialstock); i++){
+		stock[i] = initialstock[i];
+		rstock[goods[i].resource] += stock[i];
+	}
+}