New to programming. Program is not broken, but probably terrible.
Author |
Message |
Taz
|
Posted: Wed Sep 09, 2009 6:59 am Post subject: New to programming. Program is not broken, but probably terrible. |
|
|
What is it you are trying to achieve?
Essentially make a crude, text-based version of Pokemon's battle system.
Program here :
Turing: |
%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% OPENING STUFF %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%
setscreen ("nobuttonbar")
var playername : string
var starter : string
var action : string
var actiontrap : int := 0
type Pokemon :
record
Name : string
Nick : string
HP : int
Atk : int
Def : int
SpAtk : int
SpDef : int
Spd : int
end record
var poke1 : Pokemon
var poke2 : Pokemon
poke1.HP := 0
procedure battlescreen
locate (1, 1)
put playername, "'s ", poke1.Nick, "(", poke1.Name, ")"
put "HP: ", poke1.HP
put "Atk: ", poke1.Atk
put "Def: ", poke1.Def
put " "
put "VS."
put " "
put "Wild ", poke2.Name
put "HP: ", poke2.HP
put "Atk: ", poke2.Atk
put "Def: ", poke2.Def
put " "
put "--------------"
put " "
end battlescreen
poke2.Name := "PIDGEY"
poke2.HP := 14
poke2.Atk := 8
poke2.Def := 3
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% PROGRAM STARTS %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%
%%%%% NAME STUFF %%%%%
%%%%%%%%%%%%%%%%%%%%%%
put "Welcome to Pogeys."
put " "
put "What's your name?"
put "Name: " ..
get playername
delay(1000)
cls
%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% STARTER LOOP %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
loop
put "Choose your Pokemon by typing its name!"
put "[ Bulbasaur | Charmander | Squirtle | Pikachu ]"
put " "
put "Pokemon: " ..
get starter
if starter = "Bulbasaur" then
poke1.Name := "BULBASAUR"
poke1.Nick := "BULBASAUR"
poke1.HP := 20
poke1.Atk := 8
poke1.Def := 5
elsif starter = "Charmander" then
poke1.Name := "CHARMANDER"
poke1.Nick := "CHARMANDER"
poke1.HP := 16
poke1.Atk := 10
poke1.Def := 4
elsif starter = "Squirtle" then
poke1.Name := "SQUIRTLE"
poke1.Nick := "SQUIRTLE"
poke1.HP := 12
poke1.Atk := 8
poke1.Def := 6
elsif starter = "Pikachu" then
poke1.Name := "PIKACHU"
poke1.Nick := "PIKACHU"
poke1.HP := 18
poke1.Atk := 9
poke1.Def := 3
end if
if poke1.HP = 0 then
put " "
put "'", starter, "' is not a valid choice. Please choose again."
delay (1000)
cls
end if
exit when poke1.HP > 0
end loop
put " "
put "You chose ", poke1.Name, "!"
put " "
put "HP: ", poke1.HP
put "Attack: ", poke1.Atk
put "Defense: ", poke1.Def
delay (1500)
cls
put "Name your Pokemon."
put "Name: " ..
get poke1.Nick
delay (1000)
cls
put "Suddenly, a wild ", poke2.Name, " appeared!"
delay(1000)
put " "
put "Go! ", poke1.Nick, "!"
delay(1000)
%%%%%%%%%%%%%%%%%%%%%%%
%%%%% BATTLE LOOP %%%%%
%%%%%%%%%%%%%%%%%%%%%%%
loop
loop
actiontrap := 0
cls
battlescreen
locate(15, 1)
put "Options: Fight"
put ""
put "> " ..
get action
delay(1000)
battlescreen
locate (15, 1)
if action = "Fight" then
actiontrap := 1
cls
battlescreen
poke2.HP := poke2.HP - (poke1.Atk - poke2.Def )
put poke1.Nick, " attacks ", poke2.Name, "."
put poke2.Name, " received ", (poke1.Atk - poke2.Def ), " damage."
battlescreen
elsif actiontrap = 0 then
cls
battlescreen
put "'", action, "' is not a valid choice. Please choose again."
end if
delay(2000)
exit when actiontrap > 0
end loop
locate (18, 1)
poke1.HP := poke1.HP - (poke2.Atk - poke1.Def )
put poke2.Name, " attacks ", poke1.Nick, "."
put poke1.Nick, " received ", (poke2.Atk - poke1.Def ), " damage."
battlescreen
delay(2000)
cls
exit when poke1.HP <= 0
exit when poke2.HP <= 0
end loop
battlescreen
if poke1.HP <= 0 then
put " "
put poke1.Nick, " has fainted."
put playername, " is out of usable Pokemon. ", playername, " was eaten by wild Pokemon."
else put " "
put "Wild ", poke2.Name, " has fainted. You win the game."
end if
|
What is the problem you are having?
I suck at programming and don't really know what I'm doing, thus I'd like tips, pointers.
Things I specifically need help with would be:
1. When I ask a user for their Pokemon/Battle choice, it's case sensitive. I don't want it to be, but I don't know how to fix this. [Okay, I know one way, but it'd be messy.]
Additionally, I don't really know how to handle this situation at all. As you can see, for the action bit I made the variable 'actiontrap' and set it to be 0, and if actiontrap stayed '0', then it would tell them they used an invalid action. When they type a valid action, 'actiontrap' is changed to something above 0, and allows them to continue. Surely this is not the proper way to do things.
2. The battle system as a whole feels like a big mess. Because I wrote a lot of it when I was sleep deprived, it's confusing for me just to look at. I could probably have done a better job, but I feel discouraged from going back to it before getting some pointers which could potentially help me to 'neaten' things up a bit.
3. I'm not really sure on how I would produce "criticals". In other words, a percent chance [say, 5%] that an attack will do twice the damage.
4. A way to decide the order of attacks. Whichever Pokemon has the highest speed stat attacks first. I have an idea how to do this, but it'd be very ugly my way.
- extra
5. I know how to make a timer, but I don't know how to make a timer run along side, say, a request for input from the user. I can only have either the request or the timer going at a time.
This one doesn't have to do with this program, but for a different idea I had.
\ \
But really, just.. any help would be great.
Please specify what version of Turing you are using
4.1
\ \
Anyway, just to maybe clear up why this is such a mess.
Turing is my first language, thanks to a class I took for a while. Sadly, I was only in this class for about a month, and so I learned very little. [It was also a very slow class. I've read a bit of the tutorials. Whatever I understood. Not a lot really 'clicks' aside from the really basic stuff, and I think I'm more of a hands-on learner, which is why I just sort of dived into making an actual program that would interest me.
Now I'm only trying to learn, simple for the fun of it, I guess. Generally being a gamer/geek and having a big interest in AI, it seemed like a good thing to try but I have absolutely no plans to take any classes in the future. Because of this, I would also really appreciate any books being suggested. [I did a quick search for a book on 'turing', but the only results I got were on the turing machine, which doesn't help me obviously.]
About the program, it's obviously unfinished. I completed the 'core', I think, but there's so much that has to be added. I wanted to keep it mostly text based, but a bit of aesthetics would be nice. [Example; a health bar, different font for the entire program.]
Also, I'm sorry I use so many delays. I wanted the user to be able to be given a bit of a chance to read, but I haven't looked into how to have the program wait until the user presses a certain key before it continues.
And I'm sorry that my code overall probably looks horrid. It's a combination of my lack of sleep, being my first real program, and not sticking to any specific.. rules[?].
I'm pretty lost.
Thanks in advance. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
DemonWasp
|
Posted: Wed Sep 09, 2009 9:06 am Post subject: RE:New to programming. Program is not broken, but probably terrible. |
|
|
First piece of advice: your indenting is weird, press F2 to fix that. Turing's helpful indenter will fix your indenting instantly.
1. Make a function that converts a string to upper case or lower case. Convert user input to the same case as "FIGHT" or "fight", then compare them.
The "actiontrap" idea isn't bad, necessarily, but it could be a little cleaner. Your flow of control is:
code: |
main-game-loop
user-input-loop
get-user-input
if user-input-is-valid then
do-corresponding-thing
end if
end-user-input-loop
end-main-loop
|
So instead of using actiontrap, you could just put an exit command at the end of every valid action. Using exit will exit the innermost loop immediately, without proceeding to the end.
If you were to use actiontrap, I might call it valid_action and make it a boolean instead; alternately, make it action_type and have different actions be represented by different values.
2. Most of the complexity you're seeing in your battle system is because you haven't used arrays. Find the Turing Walkthrough and learn to use arrays. You can use arrays of records, as so:
Turing: | var pokemon: array 1..50 of Pokemon |
Doing so will allow you to avoid repeating code (such as code checking whether they have fainted, or having one attack another).
3. Once you've changed your combat code to use arrays, adding criticals is a matter of using Rand.Int() or Rand.Real() to get a random number. If it's above the critical percentage, then they get a critical and should have (as an example) double damage. Multiply the "damage dealt" variable by two.
4. Once you've changed your combat code to use arrays, you can easily select which combatant plays first by looking at each pokemon in the array, finding the index into the array of the one with the highest speed stat, and starting with that one's turn. If you have more than a few and they all proceed in speed-rating-order, then you should look into sorting.
5. The reason you can't have a timer running alongside user input is that you're using blocking user input. You can either switch to polling input (using Input.KeyDown), though this won't let you input strings easily, or adding another thread (using fork() ). Of the two, using Input.KeyDown is vastly preferable in Turing, because it's really really bad at multi-threading.
6. To wait until the user hits a key before continuing, you want to use getch or getchar. I don't recall how to use them, so you'll have to look them up in the Turing help yourself.
In any case, don't feel bad. Everyone here has been a newbie programmer before, and everyone has written code worse than what you've got in your post. In fact, I guarantee I have terrible code still on my hard drive, from back in grade 9 or 10. Awful code. Code that would make you cry to look at it.
Things to learn to make code prettier:
- arrays
- procedures / functions - you've already used one of these (battlescreen) but you could use one to, say, run fights, or another to check that user input is valid...
- naming conventions - choose a way of naming things that isn't ugly and stick to it. Common examples are camelCasingVariables and underscores_separate_words. For constants (like Pi, the speed of light, etc), use CAPITALS_WITH_UNDERSCORES. |
|
|
|
|
|
Taz
|
Posted: Thu Sep 10, 2009 2:09 pm Post subject: Re: New to programming. Program is not broken, but probably terrible. |
|
|
I understand mostly everything. Removed almost all delays in favor of key presses. User can now input actions in any case, as long as the word is right. 'actiontrap' removed entirely, pretty sure I won't need it now.
However, I'm totally stumped on the use of arrays in addition to records. I read the tutorials on them, and searched some other threads, but I'm not following. What it would do, how it would help in my program, etc. I imagine an example would be enough to help me understand. Well, hopefully. I believe I know the syntax, I just don't know how to make use of it.
Really appreciate the help though, already helped to fix a lot. Would probably have more to say/and more coherently, but the lack of sleep has got me again, and I've still got a few hours to zombie through before I can crash. |
|
|
|
|
|
DemonWasp
|
Posted: Thu Sep 10, 2009 3:54 pm Post subject: RE:New to programming. Program is not broken, but probably terrible. |
|
|
Using arrays lets you deal with larger numbers of objects without duplicating code. That only made sense inside my head, so here's an example, done in fake-code:
Let's suppose you have two combatants, and whichever has a higher .speed attribute goes first.
code: |
var player1;
var player2;
loop
if ( player1.speed > player2.speed ) then
do-player-turn ( 1 )
do-player-turn ( 2 )
else
do-player-turn ( 2 )
do-player-turn ( 1 )
end if
end loop
|
That looks alright, but what if we have three players?
code: |
var player1;
var player2;
var player3;
loop
???
end loop
|
Go ahead and try to fill in that (???) part yourself. Give up? I don't blame you, I did too. There are (3 factorial) = 6 possible orderings. Now imagine it with 4 players (24 orderings)...or 5 (120 orderings). Oops?
Arrays to the Rescue!
code: |
var num_players : int := 20 % Or, y'know...100.
var players: array 1..num_players of Player
sort-players-by-speed ( players )
loop
for i : 1..num_players
do-player-turn ( players(i) )
end for
end loop
|
Well now that looks better, doesn't it? |
|
|
|
|
|
|
|