Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (762)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (847)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  How would you implement sokoban  (Read 4010 times)
0 Members and 1 Guest are viewing this topic.
Offline zhengdk

Senior Newbie





« Posted 2014-04-08 12:20:58 »

I am new to Java game programming. So I started with some simple games such as snake, moon lander, and I am doing sokoban now.

Following the idea of OOP, I created Player.class, Box.class, Grid.class, and some other classes for structure. When it comes to logic, I found that those classes hinder the design.

Then I realizes it would be much easier to implement sokoban just using a 2D int array, in which the integer value presents the player, box and so on.

Perhaps it is because I am a newbie and don't know how to do things right. But I want to know what is the best way to design.
Offline trollwarrior1
« Reply #1 - Posted 2014-04-08 12:36:28 »

It doesn't matter how you make it unless you don't actually make it.
Offline LiquidNitrogen
« Reply #2 - Posted 2014-04-08 13:33:39 »

The 2d is the right way to go, but you dont have to fill it with integers. you can put your box and player objects in it, as well as other objects you want.

to do that you will have to create a super class for the various movable object types.
you have a class Mob{....}. It holds basic information like position, sprite, renderMethod(), etc. You can then make your 2d array as: Mob mobMap[][];

then you make a class for each type of object in the game:
PlayerMob extends Mob{....}
BoxMob extends Mob{....}
etc.
these can have their own additional behaviors, but they will still fit in together in your 2d array.

These concepts are very easy to find more information on, but hopefully it points you in the right direction.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline zhengdk

Senior Newbie





« Reply #3 - Posted 2014-04-08 13:50:02 »

Actually I did quite the same as you suggested. I create the Grid extends Point. But I don't just extends the Grid. Instead, for player and box, I include the Grid in them. For walls, floors, I extends.

But whatever, these classes don't help in logic, what they have are just the draw() method. Maybe I'll let them implements a Drawable interface and then put them into the array. Then I complete the logic in a Game.class, and call the draw() methods from the 2D array.

Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2014-04-08 13:51:10 »

Only a 2D array is not the way you should go, because you need to be able to place the gems onto the socket tiles.
Also, you might make a mistake in your game code somehow and end up with two players inside your array.

I would create a Grid class / simple 2D int[][], that holds what tiles are walls, what tiles are sockets and what tiles are ground that is walkable. You can simply create constants for them (i.e.
public static final int WALL = 1; public static final int GROUND = 2;
), no need for classes.
Then you add a Player and a Gem class that have x and y integer fields. They can move around, the 2D int[][] cannot change.

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline zhengdk

Senior Newbie





« Reply #5 - Posted 2014-04-08 14:13:43 »

Your propose is even closer to my origin design.

I have the Map.class which contain a Map.Type[][]. And Type is a enum { WALL, FLOOR, TARGET}. final static int is good when you need the int value, while in other situation I prefer enum.

Also, I have the box class. But then I find out I don't need this class. It will be much easier to just manuplate the 2D array. If I use 2D array, I can easily find out if the player can go where, if there is a box and what if the box is leaning on to the wall. However if the boxes are saved in a Set, I need to iterate through them every time, comparing with x, y, then checking the walls.
Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #6 - Posted 2014-04-08 14:24:00 »

Also, I have the box class. But then I find out I don't need this class. It will be much easier to just manuplate the 2D array. If I use 2D array, I can easily find out if the player can go where, if there is a box and what if the box is leaning on to the wall. However if the boxes are saved in a Set, I need to iterate through them every time, comparing with x, y, then checking the walls.

The enum is not a bad idea, it doesn't need to be used, but it doesn't hurt much anyways.
However, what if the socket tile is saved in Map's
tile[4][4];
and you finally moved the box to [icode]tile[4][4];[icode]? Would you overwrite the socket? But then you can't move the box or you would remove the socket.

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline zhengdk

Senior Newbie





« Reply #7 - Posted 2014-04-08 14:35:41 »

For that way of implementation. I would have more in the enum, BOX_ON_TARGET (CRYSTAL_IN_SOCKET).

I am very happy that someone thinks the same with me. I am going this way, to have:

class Grid extends Point {
Type type;
}

enum Type { WALL, FLOOR, BOX, TARGET, BOX_ON_TARGET}

class Player

class Game {
    Grid[][] grids;
    Player player;
}

If you feel there are better designs, please enlighten me. (or why shouldn't I do this)
Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #8 - Posted 2014-04-08 14:52:05 »

If you feel there are better designs, please enlighten me. (or why shouldn't I do this)

I realize this is somehow getting rediculous now, since it's only sokoban, but anways, I like thinking about "nearly perfect" design Smiley

Back on topic:

I don't see a reason why you should make a difference between Player and Boxes. I liked my approach (saving only walls, targets and free spaces in the 2D Array), because I would seperate movable objects from Static ones.

Also, I wouldn't call it "Grid", because a Grid encapsulates single Cells. On the first glance, something that is typed "Grid[][]" looks like a 2D array with 2D arrays (Grids) inside.

I would create the following types:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
enum Cell {
    WALL(false),
    FLOOR(true),
    TARGET(true),
    OUT_OF_LEVEL(false)

    public boolean canBeMovedOn;

    Cell(boolean canBeMovedOn) {
        this.canBeMovedOn = canBeMovedOn;
    }
}

abstract class Movable {
    private int x;
    private int y;
   
    public Movable(int startx, int starty) {
        this.x = startx;
        this.y = starty;
    }
   
    // Direction is the direction the user has pressed
    public abstract void act(Direction dir, SokobanWorld world);
}

class Box extends Movable {
    public Box(int sx, int sy) {
        super(sx, sy);
    }
   
    // Do nothing. A Box doesn't react to user input directly
    public void act(Direction dir, SokobanWorld world) {}
}

class Player extends Movable {
    public Player(int sx, int sy) {
        super(sx, sy);
    }

    public void act(Direction dir, SokobanWorld world) // To be implemented
}

class SokobanWorld {
    public Cell[][] grid;
    public Map<Vec2i, Movable> movables;
}


But this might all be over-engineered Wink

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (364 views)
2018-06-10 19:43:48

EgonOlsen (372 views)
2018-06-10 19:43:44

EgonOlsen (304 views)
2018-06-10 19:43:20

DesertCoockie (548 views)
2018-05-13 18:23:11

nelsongames (872 views)
2018-04-24 18:15:36

nelsongames (855 views)
2018-04-24 18:14:32

ivj94 (1307 views)
2018-03-24 14:47:39

ivj94 (426 views)
2018-03-24 14:46:31

ivj94 (1097 views)
2018-03-24 14:43:53

Solater (445 views)
2018-03-17 05:04:08
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!