2048 from Rosetta Code

I found this and wanted to give it a try:
https://rosettacode.org/wiki/2048#Scala

But this gives 28 errors. Is there something wrong with my environment, or with the code?

What are the errors youā€™re getting? My guess would be that this example is incomplete ā€“ that itā€™s depending on libraries you have to include in your .sbt file, but itā€™s not showing the .sbt file.

(Iā€™ll also opine that it isnā€™t especially idiomatic Scala code. It probably works, but it looks a lot like Java code that has been translated to Scala.)

I just started again with Scala after being away for a ā€˜fewā€™ years. And I really did not do anything with GUIā€™s. So I thought this could be a nice star to get on track againt. It really does something (I hope), is not overly simple, but also not very complex.

But from your comment I understand that this was not my best decision. :wink:

Anyone knows a better example?

Twenty-eight is a bit much, but it starts with:
/home/cecil/scala/Game2048.scala:12: error: type mismatch;
found : () => Unit
required: Runnable
SwingUtilities.invokeLater(() => {
^
/home/cecil/scala/Game2048.scala:25: error: not found: value Game2048
private var (tiles, gamestate)= (Array.ofDim[Tile](side, side), Game2048.State.start)
^
/home/cecil/scala/Game2048.scala:70: error: Any does not take parameters
) if (Option(tilesĀ®Ā©).isEmpty) {
^
/home/cecil/scala/Game2048.scala:82: error: not found: value Game2048
if (gamestate == Game2048.State.won) g.drawString(ā€œyou made it!ā€, 390, 350)
^
/home/cecil/scala/Game2048.scala:83: error: not found: value Game2048
else if (gamestate == Game2048.State.over) g.drawString(ā€œgame overā€, 400, 350)
^
/home/cecil/scala/Game2048.scala:91: error: Any does not take parameters
val value = tilesĀ®Ā©.value
^
/home/cecil/scala/Game2048.scala:96: error: value getAscent is not a member of Any
val asc = fm.getAscent
^
/home/cecil/scala/Game2048.scala:97: error: value stringWidth is not a member of Any
val (x, y) = (215 + c * 121 + (106 - fm.stringWidth(s)) / 2,115 + r * 121 + (asc + (106 - (asc + fm.getDescent)) /

Hmm. I donā€™t have access to an IDE at the moment, but when I plug this into Scastie it seems to be compiling successfully. (Itā€™s failing at runtime, but thatā€™s expected given that Iā€™m trying to run a desktop application from a web browser.)

So a different question: how are you compiling this? Iā€™m wondering if the issue is environmental.

That said ā€“ as Iā€™ve mentioned before, I personally prefer to build stuff with Web UIs these days. If you have any interest in that, Iā€™d recommend the Scala.js SPA tutorial, which is a very idiomatic example of a client-server web application. Or possibly the Hands-on Scala.js tutorial, which provides more information about building something entirely in the client, which works well for a lot of use cases. (You can now build very sophisticated applications purely client-side, if you donā€™t need persistence. Thatā€™s the way I would personally do something like a 2048 game.)

Are you maybe using an older version of scala? The first type mismatch comes from using a lambda to instantiate a ā€œSAMā€ (Single Abstract Method) interface, which is only supported since Scala 2.12.

1 Like

I do not compile it yet. I just run it with ā€˜scala Game2048.scalaā€™.

I find sbt a bit cumbersome to use. I probably need to dig into sbt.

That is the problem. I am using Debian and there they use 2.11.8. So it is my environment.

Ah. This is another reason to get sbt and start using it ā€“ it lets you simply declare your target version of Scala for a project, and auto-downloads it when needed. In my experience, itā€™s actually pretty unusual to run something directly with the scala command. (Iā€™ve never done so, in six years of professional Scala experience ā€“ indeed, Iā€™ve never directly installed Scala in my main development environments.)

I would recommend installing sbt, use the ā€œsbt newā€ command to generate a new project, and then put this file into there to build and run it. Thatā€™s a much more conventional Scala development environmentā€¦

That works. The reason I used scala instead of sbt is that I wrote a little mancala engine and with just using scala instead of sbt it runs much faster.
I probably need to dive into how sbt works.
Thanks.

I understood the code is not really scala code, but more translated Java code. What would be a good way to rewrite it?

Itā€™s unlikely that thereā€™s much difference in the speed of the actual program ā€“ itā€™s just that sbt is really slow to boot. Itā€™s a build tool, and isnā€™t really intended for use at runtime. (I tend to just leave it running in a separate window.)

(Thereā€™s also been a fair amount of progress on boot speed, although itā€™s far from perfect. If this sort of thing matters to you, I recommend looking into ā€œbloopā€.)

Well, the biggest difference I notice offhand is that the algorithm does an awful lot of mutable rewriting of structures. The move() function is a classic example: it is mutating the game state under the hood, and then just returning a flag of whether it did something. By contrast, if I was teaching this as a Scala example, Iā€™d want that function to compute the new game state and return it, but not to change any external vars.

Really, thatā€™s the heart of it right there, and itā€™s a topic that comes up here frequently: when I think of ā€œgoodā€ Scala code, it usually tries to minimize the use of non-local vars. You sometimes need them for efficiency, and there are specific cases where they are idiomatic, but (unlike Java) they arenā€™t a tool I would recommend normally reaching for. Instead, I recommend leaning towards writing ā€œpureā€ functions (take parameters, return a result, donā€™t do any side-effects) except when you have to break out of that for practical reasons.

That is what I mend. The overhead from sbt means that with scala the program is already finished, when with sbt it starts executing. I have to evaluate the different possibilities.

I will look in your tips for rewriting.

Thanks.

I suppose, but only because youā€™re building a toy program in an unusual way ā€“ I believe your observed results would be very different for a real program of any serious scale, especially when youā€™re actually running it rather than developing it. So I donā€™t recommend generalizing from this observationā€¦

Yes, with continuously having a sbt instamce open it really is a lot less a problem. So I just need to create an extra console with an opened sbt.

Yeah, I pretty much always run that way. (Even when using the IntelliJ IDE I usually have a Terminal window open.)