For fun: rushhour game

Summer is coming, but it’s too hot outside, so let’s have fun inside. I googled around to see how the rush hour game is implemented in Prolog, and I wonder how a 6x6 rectangular game should be represented.

like this?

[ [-, -, -, -, -, -],
  [-, -, -, -, b, -],
  [-, -, r, r, b, -],
  [-, -, -, -, b, -],
  [-, -, -, -, -, -],
  [-, -, -, -, -, -] ]

I would need to define moves by moving the list elements, which is easy horizontally, see docs for nth0/4 (I guess this works both ways, left and right):

edge(List, Index, OldElem, NewElem, NewList) :-
    nth0(Index, List, OldElem, Transfer),
    OldElem = [-, R2, R3, R4, R5, R6],
    NewElem = [R2, R3, R4, R5, R6, -],
    nth0(Index, NewList, NewElem, Transfer).

How do I do this vertically? Does it make sense to structure the array in matrix form at all (and use some of the matrix packs to transpose the matrix), or should I use a flat list and implement the moves with indices?

Efficiency is not needed. I found some solutions in the internet, but they are not pretty (and I want to solve it myself).

Ops, it’s not that trivial… We don’t want to break the blue bus :slight_smile:

[ [-, -, -, -, -, -],
  [-, -, -, -, b, -],
  [-, r, r, b, -, -],
  [-, -, -, -, b, -],
  [-, -, -, -, -, -],
  [-, -, -, -, -, -] ]

I solved the problem by using a list of car/3 compounds, with atoms for Color, Orientation and a list for the positions occupied.

  • move a horizontal car left: maplist sum(1) for all positions (or -1, or +/- 10 for vertical cars)
  • check if a border is reached by constraining positions to be between 11…16 or 21…26 etc.
  • check if cars collide by appending their positions, length N, sorting them and testing if length is still N

The rest is breadth search (and I will add a heuristic to prefer the red car close to 35/36 to simulate my nephew‘s strategy).

  • The check for the border could be removed by adding a big accordion bus at 10…17, 20, 30, …70…77, 67, 57, …, 27. That bus doesn’t move.
  • The check for collision could be improved by keeping track the empty spaces (then we don’t need the accordion bus either).
  • Todo: render the game on SWISH using Unicode car signs :sport_utility_vehicle::oncoming_automobile::taxi::oncoming_taxi::automobile::oncoming_police_car::fire_engine::minibus:

Hey, this is cool. We need more games written in Prolog. Maaany more.

I’ve got some code I use to print out and walk through grids of ASCII symbols. It was originally used to generate the figures and animations on this project:

There’s a video at the top of the page that will take a while to load because I’m a dork and I didn’t know how to make it smaller while retaining quality.

Anyway there’s a newer, more light-weight version of this library that I use to create images like this one:

I thought I could use the same library to create the maps for a roguelike or similar kind of ASCII-graphics based game that could run on a terminal with a rule engine in Prolog.

Do you think that could work with your game? Interested in collaborating? I have some free time!

P.S. I’m a complete beginner in graphics and I’m probably doing it all in the most inefficient way possible. For example in the screenshot above the image is created by stitching together smaller images (the ones with the green squares and gray dots). You can see the “seams” between images and the direction in which a new image is stuck to a previous one in the lines of yellow arrows. The whole thing just loops through the images to stitch together and takes one as a reference, then one of eight compass direction for all the remaining ones. The blue lines show where the composite images are stuck together in a longer row. It’s very primitive and I’m sure there must be much better ways to do, e.g. use a ncurses-like library however I didn’t have much luck with a Python ncurses clone I tried so I rolled my own in Prolog. Suggestions welcome!

accidentally continued a new thread, sorry

Coming at things from the other end, I’ve started working on a graphics library for Prolog, using a games-engine-inspired ECS design. Eventually I hope to use it to make a game, but perhaps in the meantime some other enterprising folks might find a use for it. I’m planning on making more of an announcement about this when it’s more ready, but if anyone wants to play around with such a thing, you can find the source & some examples of use here: ~jamesnvc/logui - SDL + Prolog experiment - sourcehut git

I am very sorry that I did not reply earlier, my university is moving to a new cloud service, and now all my files are distributed across several computers :-/ I can describe the representation, though. It’s quite simple:

  • the game is just a list of cars: [Car1, Car2, Car3 | Etc]
  • the car is a simple compound: car(Color, X, Y, Orientation, Length)

Goal is to render this on a 6x6 ASCII array (well, not ASCII, better Unicode). For simplicity, the cars could be repeated to indicate their length:

:sport_utility_vehicle:
:sport_utility_vehicle::automobile::automobile:
:sport_utility_vehicle:

So, to render the game, we probably need some occupied/4 predicate:

occupied(X, Y, car(C, SX, Y, horizontal, Length), Color) :-
    X >= SX, X =< SX + Length,
    !, Color = C.
occupied(X, Y, car(C, X, SY, vertical, Length), Color) :-
    Y >= SY, Y =< SY + Length,
    !, Color = C.
occupied(_, _, _, blank).

If the list of cars is in Game, we can maplist(occupied(X, Y), Game, Color) over it to get the colors. X and Y would loop over 1…6.

My main question is how to integrate this into some portray-hook, and maybe later have something that works in html and SWISH. Somewhere in the code I found some portray for html.

See SWISH -- SWI-Prolog for SHaring. Not sure about the best HTML representation for the board. Possibly a square <div> for the board and then <div>'s using absolute positions for each of the cars?

Given that this seems to be SDL based, I wonder whether we can/should add this as an xpce extension. After all, current xpce uses SDL3 and a lot of logic is already there to deal with keeping the Prolog toplevel accessible, getting the stuff built cross platform, etc. xpce “misuses” SDL a bit in the sense that it builds a widget and 2D graphics object layer on top of SDL and does nothing with the video support (it mainly uses Cairo and Pango to fill SDL surfaces that are displayed in the SDL window). But, I assume it can host an SDL window the way SDL is intended to be used as well :slight_smile: It should also be pretty straightforward to add sound and additional input devices.

Ugh. Seems go-away thinks I’m a bot. Reminds me of that time my friend asked a co-worker “why do I have a ‘Intel Inside’ sticker on my hand?”. The co-worker pointed out that my friend lives with someone who studies AI. Sneaky git. It was just transferred from my friend’s laptop.

Er with that digression I guess I’ll have to get the repo and figure out how to run this locally.

We really should have some Prolog games. I wonder why we almost never see any :roll_eyes:

EDIT: hey, alright, I’m through go-away. I just had to wait a bit. Good thing I didn’t close the page.

Oh, perhaps! I kind of started this project to experiment with an alternate approach to XPCE, trying to find a way that felt more “idiomatic” to “normal” Prolog to me than PCE (and more me to learn more about SDL and Cmake). Perhaps it would be easier to build on top of that though…actually, the way things are architected in my library, the ECS layer is separate from the SDL layer, so it would be possible to have another implementation of the graphics presenting the same API, I suppose.

Ho, that’s nice.
I tried something similar sometimes ago: GitHub - kwon-young/sdlpl: SWI-Prolog bindings to SDL · GitHub
This was just an experiment while making a very low level pure prolog interface to sdl and implement a gui library similar to QML from the Qt framework.

How did you choose to design the memory management for DSL specific resources ?
In my case, I put each resource in a blob, but had a hard time modeling resources dependencies.

One thing that would be amazing would be to ship a low level memory safe prolog interface to sdl (and maybe also to drawing primitives from cairo and pango) in swi-prolog so that we could experiment creating gui framework in pure prolog !

Well, the current xpce (from GIT) is in principle memory and thread-safe. The main hole in memory safety were the @Integer references to xpce objects. XPCE could reclaim these objects, after which trying to find it again from @Integer was mostly heuristic; checking the address is sane and there is something there that looks like an object at that address. The latest GIT version uses SWI-Prolog blobs to reference xpce objects, which is safe. This means xpce (reference based) and Prolog (atom) garbage collection now cooperate. Most seems to run fine. Some regression is to be expected as part of the code assumes @Integer or assumes an atomic/1 type is never an object reference. Most have been fixed.

This makes xpce basically a safe system. Its current thread model is pretty much the same as Python’s GIL based model, i.e., multiple threads may be active, but only one may actually run in xpce itself at any point in time. xpce calling out to Prolog unlocks xpce for other threads. Note that SDL’s API needs to be called mostly from the SDL (main) thread anyway. As is, most xpce objects are not directly related to SDL though. They are date only or talk to Cairo/Pango, which are thread-safe. Only windows and screens (displays) map to SDL and thus most window and display operations need to be called from the main thread.

For short, I think xpce is a sound base for exposing SDL to Prolog. All we need to do is to expose more of SDL to XPCE/Prolog and invent a more Prolog spirit way to interact with the GUI.

I have put the code here, feel free to improve it. The red car should be the first in the list.

I did the same, put them in blobs, then have the “systems” in ECS parlance handle the dependencies between resources.