Solitiare card game - how to program resume game function? - lua

I've been programming a solitaire card game and all has been going well so far, the basic engine works fine and I even programmed features like auto move on click and auto complete when won, unlimited undo/redo etc. But now I've realised the game cannot be fully resumed ie saved so as to continue from the exact position last time the game was open.
I'm wondering how an experienced programmer would approach this since it doesn't seem so simple like with other games where just saving various numbers, like the level number etc is sufficient for resuming the game.
The way it is now, all game objects are created on a new game, the cards, the slots for foundations, tableaus etc and then the cards are shuffled and dealt out. This is random but the way I see it, the game needs to remember this random deal to resume game and deal it again exactly the same when the game is resumed. Then all moves that were executed have to be executed as they were as well. So it looks like the game was as it was last time it was played, but in fact all moves have been executed from beginning again. Not sure if this is the best way to do it but am interested in other ways if there are any.
I'm wondering if any experienced programmers could tell me how they would approach this and perhaps give some tips/advice etc.

(I am going to assume this is standard, Klondike Solitaire)
I would recommend designing a save structure. Each card should have a suit and a value variable, so I would write out:
[DECK_UNTURNED]
H 1
H 10
S 7
C 2
...
[DECK_UNTURNED_END]
[DECK_TURNED]
...
[DECK_TURNED_END]
etc
I would do that for each location cards can be stacked (I believe you called them foundations), the unrevealed deck cards, the revealed deck cards, each of the seven main slots, and the four winning slots. Make sure however you read them in and out, they end up in the same order, of course.
When you go to read the file, a simple way is to read the entire file into a vector of strings. Then you iterate through the vector until you find one of your blocks.
if( vector[ iter ] == "[DECK_UNTURNED]" )
Now you go into another loop, using the same vector and iter, and keep reading in those cards until you reach the associated end block.
while( vector[ iter ] != "[DECK_UNTURNED_END]" )
read cards...
++iter
This is how I generally do all my save files. Create [DATA] blocks, and read in until you reach the end block. It is not very elaborate, but it works.

Your idea of replaying the game up to a point is good. Just save the undo info and redo it at load time.

Related

OPENCV OPENVINO cv2.rectangle

I am using opencv and openvino and am trying to figure out when I have a face detected, use the cv2.rectangle and have my coordinates sent but only on the first person bounded by the box so it can move the motors because when it sees multiple people it sends multiple coordinates and thus causing the servo and stepper motors to go crazy. Any help would be appreciated. Thank you
Generally, each code would run line by line. You'll need to create a proper function for each scenario so that the data could be handled and processed properly. In short, you'll need to implement error handling and data handling (probably more than these, depending on your software/hardware design). If you are trying to implement multiple threads of executions at the same time, it is better to use multithreading.
Besides, you are using 2 types of motors. Simply taking in all data is inefficient and prone to cause missing data. You'll need to be clear about what servo motor and stepper motor tasks are, the relations between coordinates, who will trigger what, if something fails or some sequence is missing then do task X, etc.
For example, the sequence of Data A should produce Result A but it is halted halfway because Data B went into the buffer and interfered with Result A and at the same time screwed Result B which was anticipated to happen. (This is what happened in your program)
It's good to review and design your whole process by creating a coding flowchart (a diagram that represents an algorithm). It will give you a clear idea of what should happen for each sequence of code. Then, design a proper handler for each situation.
Can you share more insights of your (pseudo-)code, please?
It sounds easy - you trigger a face-detection inference-request and you get a list/vector with all detected faces (the region-of-interest for each detected face) (including false-positive and false-positives, requiring some consistency-checks to filter those).
If you are interested in the first detected face only - then it could be to just process the first returned result from the list/vector.
However, you will see that sometimes the order of results might change, i.e. when 2 faces A and B were detected, in the next run it could still return faces, but B first and then A.
You could add object-tracking on top of face-detection to make sure you always process the same face.
(But even that could fail sometimes)

I'm trying to get "leaves" to produce a rustling noise in a Roblox game by monitoring all child parts of the script

Using the Child-monitoring script #Kylaaa helped me with in another question, I've spent hours on this, altering the core functionality from healing and disappearing bricks to play a parent sound when the player "walks through the leaves". I've been studying various aspects of the problem ('IsA', 'TouchInterest', 'If...then', Classes, Operators, etc.), and done various things, such as altering my script to look at the name of touched objects instead of their classes, but I've had no luck getting the sound to play.
-- create a helper function to access the brick and the thing that touched it
function OnTouched(thing)
local active = false --start with this debounce variable off so that the function will run the first time
return function(target) --provides actual target of the event
if active then return end -- do not do the animation again if it has already started
local player=thing.Parent:findFirstChild("Humanoid") --determine if it's humanoid
if player then --if it is, then
active = true --toggle to prevent function from running again simultaneously
script.Parent:play() --play rustling leaves sound
wait(1)
active = false -- reset so function can be used again
end --end of if statement
end
end
-- loop over the children and connect touch events
local bricks = script:GetChildren()
for i, brick in ipairs(bricks) do
if brick:IsA("Part") then
local onTouchedFunc = OnTouched(brick)
brick.Touched:Connect(onTouchedFunc)
end
end
This is a shot of the leaf litter I want to add the rustling sound to. I also have the same problem with the vines on the left side.
Vines:
All leaves are 'MeshParts' with 'SurfaceAppearance' inside, and are Anchored and CanTouch but not CanCollide. I tried turning on CanCollide but it didn't help.
Dense Leaf patch properties:
Surface Appearance properties:
I had tried "if brick:IsA("Model" or "MeshPart") then"
and
"if brick.Name=="Dense Leaf patch" or "SurfaceAppearance" or "DenseLeafPatch" then"
but neither of those worked.
I then noticed that a TouchInterest wasn't generated by Roblox, and I learned that you can neither copy nor duplicate TouchInterests to use where you need them (they're not there for developers, according to a message in the DevForum).
I originally had 1-3 leaves 'MeshPart's in separate 'Model's, but then made a single, invisible part (name: TouchInterest), CanTouch not CanCollide, that was large enough to cover almost all of the physical area of the instances, and put all of the MeshParts into that part. Then, I altered the script to just look for 'Part's. As a result, a TouchInterest does get generated during run-time.
This is all of the stuff involved in the group "leaves", with the sound, then the script, the containing part, then all the leaves inside as children of the script.
Sound's properties:
No errors for this were in the Output.
I feel like there's something simple I don't understand. Do I need several small parts (instead of the one large one) encompassing groups of leaves? Please help!
I figured out the problems.
On line 6, I used "thing" when I should've used "target".
On line 9, I forgot to capitalize "Play".
On line 10, I needed to make the wait 2 seconds instead of 1.

What are the things that I should save to a file/db with Reinforcement Learning?

I'm trying to get into machine learning, and decided to try things out for myself. I wrote a small tic-tac-toe game. So far, the computer plays against itself using random moves.
Now, I want to apply reinforcement learning by writing an agent that will explore or exploit based on the knowledge it has on the current state of the board.
The part I don't understand is this:
What does the agent use to train itself for the current state? Lets say a RNG bot (o) player does this:
[..][..][..]
[..][x][o]
[..][..][..]
Now the agent has to decide what the best move should be. A well trained one would pick 1st, 3rd, 7th or 9th. Does it look up a similar state in the DB that led him to a win? Because if so, I think I will need to save every single move into the DB up to eventually it's end state (win/lose/draw state), and that would be quite a lot of data for a single play?
If I'm thinking this through wrong, I would like to know how to this correctly.
Learning
1) Observe a current board state s;
2) Make a next move based on the distribution of all available V(s') of next moves. Strictly the choice is often based on Boltzman’s distribution of V(s'), but can be simplified to maximum-value move (greedy) or, with some probability epsilon, a random move as you are using;
3) Record s' in a sequence;
4) If the game finishes, it updates the values of the visited states in the sequence and starts over again; otherwise, go to 1).
Game Playing
1) Observe a current board state s;
2) Make a next move based on the distribution of all available V(s') of next moves;
3) Until the game is over and it starts over again; otherwise, go to 1).
Regarding your question, yes the look-up table in Game Playing phase is built up in the Learning phase. Every time the state is chosen from the all the V(s) with a maximum possible number of 3^9=19683. Here is a sample code written by Python that runs 10000 games in training.

What's a good way to generate levels? How does a game like Defender (Droid Hen) generate their levels?

I started making a game for iPhone and just wondering what would be the best way to generate the levels? The way I currently am doing it is I can create Level files and then load them in through the functions, but what if I have over 100 levels? Am I supposed to create 100 files?
A game like Defender (By DroidHen) has maybe 1000 levels... I don't know because I stopped after like 600.. Are they supposed to have 1000 files? Or do they just have like 1 basic structure and then just use a random layout function that generates the enemies?
I just need some insight on this so I can get an idea of how to perform this task... If this is the wrong place to ask this question just please let me know where else I could ask
There are a number of ways to tackle this, depending on your game design. Obviously (?), manually-created levels that are tweaked for being "interesting" are best, but algorithmic level generation can mean potentially unlimited replayability (if your basic game design is solid).
You don't necessarily need to have one file per level, though that's a common-enough design.
The game you mentioned seems to be a "waves of enemies" style game (it's basically tower defense). It's really easy to come up with a very compact representation of each level in that case. You just keep a list for each "level" of how many of which enemy show up, and how much time to leave between them appearing.
So, an individual level could be something like:
"5A,500,10B"
That'd mean "create 5 type 'A' enemies, wait 500ms (1/2 second), then generate 5 type 'B' enemies".
You could fit thousands of those levels into a reasonably-compact source file.
Another option for more-complex game designs is to generate a large number of random levels, and manually select the "good" ones. If you save just the seeds for the random generator, that's a very compact representation.

How do video games efficiently store/retrieve large amounts of data?

For example, in Fallout 3, a save game stores the state and location of every single object and NPC in the game, and only takes up a few MB's. How do they do that!?!?
And then, during game play, how is this data added/retrieved in/from memory such that it can be displayed to the player in real-time?
UPDATED: (I'm going to make you work for your answers :P)
Based on Kevin Crowell's answer...
So I guess you would have a rendering distance that would apply to objects and NPC's, and you would "SELECT" the objects and NPC's within the given range. However, what type of data store would you use in order to get these objects?
In other words, you would you have a gigantic array of every object in the game, and constantly update a smaller list that holds the visible objects to render?
Also, per Chaos' answer...
Would would happen if you eventually touched every object in the game? Would your save game get bigger and bigger? In the case of Fallout 3, I'm pretty sure there aren't "stages", where the past data could just be dropped. Everything is persisted when you leave/return to a location. So how do you think this specific case is implemented?
With all the big hardisks nowaday, even developers seem to forget how many bytes there are in a megabyte. So to answer the question in the title: games store large amounts of data by creating savegames that are several megabyte large.
To illustrate how big a megabyte is, it's 8 million bits. That is sufficient to encode 2^8000000 = 10^2666666 states. In comparison, there are only 10^80 atoms in the universe. Now in a (save)game there are multiple subsystems with distinct states; e.g. in a RPG each NPC has its own state. But how much of a state is there, really? Their position in a town might be saved as 16 bits (do you remember their exact position if they're walking around anyway?). Their mood/disposition/etc as another 8 bits, and that allows for more emotions then some people have.
When it comes to storing this kind of data in-game, the typical datastructure is a QuadTree. This is a datastructure that allows you to determine objects in a certain X-Y region in O(log N). In some cases, game developers find it easier to pre-partition the world in zones. This reduces the amount of run-time calculations. A good example was Doom. Its maps had visibility pre-calculated; for each point one could determine quickly to which zone it belonged, and for each zone the amount of visible objects was pre-calculated. This reduced the amount of objects that needed runtime visibility checks.
It can simply be mapping objects, or NPCs, to an X,Y,Z coordinate plane. That information that be stored cheaply.
During gameplay, all of those objects are still mapped to a coordinate system at all times. They just need to read in the save information and start from there.
I think you're overestimating the complexity of what's being stored/retrieved. You don't need to store the 3D models for the objects, or their textures, or any of the things that make up large parts of a game's size-on-disk.
First of all, as chaos mentioned, it's only necessary to store information about things that have been moved. Even then, you probably only need to store, for each of those, the new position and orientation (assuming there's not other variables involved, like "damaged"). So that's two vectors for each object, which will be around a grand total of 24 bytes per object. That means you can store the information for 40,000 objects per megabyte. That's an awful lot of objects to have moved around.
Restoring this data is no more complex than placing the objects in the first place. Every object has to have a default position/orientation defined for the game to put it somewhere, so all you're doing is replacing the default with the stored value in the save file. This is not complex, and doesn't require any significant additional processing.
In Fallout 3 in particular, the map is divided in a grid fashion. You can only see your current square and the ones immediately next. The type of data store is not really important - can be a SQLite database, can be a tree serialized to disk, or can be something else entirely.
...you would you have a
gigantic array of every object in the
game, and constantly update a smaller
list that holds the visible objects to
render?
Generally yes, but the "gigantic array" doesn't need to be in memory. And there are more lists - objects in current and adjacent grid square (you can be attacked from behind - not in visible list), the visible list, the timer list...
Would would happen if you eventually touched every object in the game? Would your save
game get bigger and bigger?
Could - if there is a default state table for everything, the save can contain only the differences. The save will then grow as you progress.
Everything is persisted when you leave/return to a location.
Nope. Items you drop outside of your house will eventually disappear. Bodies too, probably. Random monsters are respawned every once in a while. This is both convenient to game designers and consistent with the real world.
If you think about the information you need to save it's really not that much;
E.g.
Position
Orientation
Inventory
Health
Objective-state
There are lots more of course, many of which dependend on both the type of game and how the save structure is organized.
Some games like Resident Evil only allow saves when you enter a new zone meaning you don't have to store all the information for entities in both zones. When you "load" a save their attributes come from the disc.
As to how this is data is retrieved/modofied, I'm not quite sure I understand. It's just data in the consoles memory. When the player saves it's written to the save device, and when they load it's restored.
One major technique is differential saves: only saving state that's something other than its default. Compare and contrast "saving the state and location of every object in the game world" with "saving the state and location of every object in the game world that the player has moved or altered".
Echoing the other answers, the biggest savings comes from eliminating all unnecessary state data.
If you look at 8-bit side-scroller games, they will start discarding state as soon as things are offscreen, and oftentimes retain nothing, because their resources are too tight to keep around more than the minimum number of instances.
Doing it on the macro-level for a game like Fallout 3 is just a matter of increasing the scope of the problem. You start sectioning up the landscape by grid or other geometrical methods, and spawn/despawn stuff as the player moves from one section to the next. You ideally keep the size of each area small so that in-memory state is not high. You figure out the bare minimum of state needed to keep around NPC and item instances, and in the layout data you tag as much as possible to auto-respawn so that it doesn't need any state saved.
If you want to be pointed at a specific data structure, an example serialization format might be a linear stream indexed by a tree of pointers, where the organization of the tree corresponds to the map layout.
On a related note, game engines often employ Zip compression, to keep the size of all that content down and also make some operations faster.
Besides what everybody else said, i would like to add state doesn't necessarly imply just position and movement,but also properites for the respective state. Usually a Game Engine has a feature witch allows you to save the data of a certain class.
Say you have a Player class and you are well into the story, when you click save the possible data that can be stored is :
Where is the player located in the
level/map
What are his attributes :
health,mana,strenght,
intelligence,etc
What skills does he have.
What level is he.
Globally we can also have:
How many references (names that allow the engine to pick up an object from a list) to objects are being stored in that specific level,in other words when you load what objects should be loaded along with it.
Are we using physics, if so who uses it.
And many more. Fallout 3 has one type of save, another game will have another. It really depends on the genre and the engine in use.

Resources