Fixing my basic Lua battle system [closed] - debugging
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
This is a problem that I cannot seem to fix. I am a very new programmer and I love to code, however, I need help with this extremely basic battle system that I'm sure all you won't mind giving me. It isn't good looking or clean, so any tips on how I could shorten my code will also be greatly appreciated.
local function battle() -- All of this is 100% unfinished, by the way
n = math.random(10) + 1 -- Everybody's HP, enemy HP randomly generated number from 10 to 100
enemyhp = 10*n
herohp = 100
io.write("Your HP: ")
io.write(herohp)
io.write(" ")
io.flush()
io.write("Enemy HP: ")
io.write(enemyhp)
io.write(" ")
io.flush()
if enemyhp <= 0 then
print("You won!")
end
local function attack() -- Attacking the enemy or running away
print("|Attack|Flee|")
input = io.read()
if input = "attack" then -- This is where my error is
attackdamage = math.random(51)
if attackdamage = 51 then
print("Critical Hit!")
enemyhp - 100
else
enemyhp - attackdamage
print("Enemy took ")
io.write(attackdamage)
io.write(" damage!")
elseif input = "flee" then
print("You ran away!")
end
end
end
Thank you.
You are missing the end of your if block. It should be
if enemyhp <= 0 then
print("You won!")
end
Second problem is the line you point to: You need to compare using two equal signs (==) instead of one:
if input == "attack" then
Then when you assign value to some variable, you need to use one equal sign. Otherwise it is just expression with no meaning.
enemyhp = enemyhp - 100
and then the same errors repeat (you have one additional end in the end too). Full code, you can compile/run: http://ideone.com/dgPoZo
local function battle() -- All of this is 100% unfinished, by the way
n = math.random(10) + 1 -- Everybody's HP, enemy HP randomly generated number from 10 to 100
enemyhp = 10*n
herohp = 100
io.write("Your HP: ")
io.write(herohp)
io.write(" ")
io.flush()
io.write("Enemy HP: ")
io.write(enemyhp)
io.write(" ")
io.flush()
if enemyhp <= 0 then
print("You won!")
end
end
local function attack() -- Attacking the enemy or running away
print("|Attack|Flee|")
input = io.read()
if input == "attack" then -- This is where my error is
attackdamage = math.random(51)
if attackdamage == 51 then
print("Critical Hit!")
enemyhp = enemyhp - 100
else
enemyhp = enemyhp - attackdamage
print("Enemy took ")
io.write(attackdamage)
io.write(" damage!")
end
elseif input == "flee" then
print("You ran away!")
end
end
Related
Can this Crystal benchmark code be improved significantly?
I'm deciding on a language to use for back-end use. I've looked at Go, Rust, C++, and I thought I'd look at Crystal because it did reasonably well in some benchmarks. Speed is not the ultimate requirement, however speed is important. The syntax is equally important, and I'm not averse to the Crystal syntax. The simple benchmark that I wrote is only a small part of the evaluation and it's also partly familiarisation. I'm using Windows, so I'm using Crystal 0.35.1 on Win10 2004-19041.329 with WSL2 and Ubuntu 20.04 LTS. I don't know if WSL2 has any impact on performance. The benchmark is primarily using integer arithmetic. Go, Rust, and C++ have almost equal performance to each other (on Win10). I've translated that code to Crystal, and it runs a fair bit slower than those three. Out of simple curiosity I also ran the code on Dart (on Win10), and it ran (very surprisingly) almost twice as fast as those three. I do understand that a simple benchmark does not say a lot. I notice from a recent post that Crystal is more efficient with floats than integers, however this was and is aimed at integers. This is my first Crystal program, so I thought I should ask - is there any simple improvements I can make to the code for performance? I don't want to improve the algorithm other than to correct errors, because all are using this algorithm. The code is as follows: # ------ Prime-number counter. -----# # Brian 25-Jun-2020 Program written - my first Crystal program. # -------- METHOD TO CALCULATE APPROXIMATE SQRT ----------# def fnCalcSqrt(iCurrVal) # Calculate approximate sqrt iPrevDiv = 0.to_i64 iDiv = (iCurrVal // 10) if iDiv < 2 iDiv = 2 end while (true) begin iProd = (iDiv * iDiv) rescue vError puts "Error = #{vError}, iDiv = #{iDiv}, iCurrVal = #{iCurrVal}" exit end if iPrevDiv < iDiv iDiff = ((iDiv - iPrevDiv) // 2) else iDiff = ((iPrevDiv - iDiv) // 2) end iPrevDiv = iDiv if iProd < iCurrVal # iDiv IS TOO LOW # if iDiff < 1 iDiff = 1 end iDiv += iDiff else if iDiff < 2 return iDiv end iDiv -= iDiff end end end # ---------- PROGRAM MAINLINE --------------# print "\nCalculate Primes from 1 to selected number" #iMills = uninitialized Int32 # CHANGED THIS BECAUSE IN --release DOES NOT WORK iMills = 0.to_i32 while iMills < 1 || iMills > 100 print "\nEnter the ending number of millions (1 to 100) : " sInput = gets if sInput == "" exit end iTemp = sInput.try &.to_i32? if !iTemp puts "Please enter a valid number" puts "iMills = #{iTemp}" elsif iTemp > 100 # > 100m puts "Invalid - too big must be from 1 to 100 (million)" elsif iTemp < 1 puts "Invalid - too small - must be from 1 to 100 (million)" else iMills = iTemp end end #iCurrVal = 2 # THIS CAUSES ARITHMETIC OVERFLOW IN SQRT CALC. iCurrVal = 2.to_i64 iEndVal = iMills * 1_000_000 iPrimeTot = 0 # ----- START OF PRIME NUMBER CALCULATION -----# sEndVal = iEndVal.format(',', group: 3) # => eg. "10,000,000" puts "Calculating number of prime numbers from 2 to #{sEndVal} ......" vStartTime = Time.monotonic while iCurrVal <= iEndVal if iCurrVal % 2 != 0 || iCurrVal == 2 iSqrt = fnCalcSqrt(iCurrVal) tfPrime = true # INIT iDiv = 2 while iDiv <= iSqrt if ((iCurrVal % iDiv) == 0) tfPrime = (iDiv == iCurrVal); break; end iDiv += 1 end if (tfPrime) iPrimeTot+=1; end end iCurrVal += 1 end puts "Elapsed time = #{Time.monotonic - vStartTime}" puts "prime total = #{iPrimeTot}"
You need to compile with --release flag. By default, the Crystal compiler is focused on compilation speed, so you get a compiled program fast. This is particularly important during development. If you want a program that runs fast, you need to pass the --release flag which tells the compiler to take time for optimizations (that's handled by LLVM btw.). You might also be able to shave off some time by using wrapping operators like &+ in location where it's guaranteed that the result can'd overflow. That skips some overflow checks. A few other remarks: Instead of 0.to_i64, you can just use a Int64 literal: 0_i64. iMills = uninitialized Int32 Don't use uninitialized here. It's completely wrong. You want that variable to be initialized. There are some use cases for uninitialized in C bindings and some very specific, low-level implementations. It should never be used in most regular code. I notice from a recent post that Crystal is more efficient with floats than integers Where did you read that? Adding type prefixes to identifiers doesn't seem to be very useful in Crystal. The compiler already keeps track of the types. You as the developer shouldn't have to do that, too. I've never seen that before.
How to create a Roblox game where the player has to guess a randomly generated pin?
So, I've been working on this for the past week. I have tried everything (based on the knowledge I know) and yet nothing... my code didn't work the first time, the second time, the third time... the forth... etc... at the end, I let frustration take control of me and I ended up deleting the whole script. Luckily not the parts and models, otherwise I'm really screwed... I need to create a game in which I have to create a keypad of sorts, at first I thought GUI would work... no, it needs to be SurfaceGUI, which I don't know how to handle well... Anyway, I needed to create a keypad using SurfaceGUI, and display it on a separate screen, as a typical keypad would... The Player would first have to enter an "initial" number, meaning in order to enter the randomly generated number he first needed to input the static pin in order to "log in," after that, then he would try to guess the number... I've literally tried everything I could but nothing... It's mainly because of my lack of experience in LUA, I'm more advanced in Python and barely know a thing in Java... If someone could assist me on how to do this, I would appreciate it greatly
First, download this and put it in a ScreenGui in StarterGui. Then, use the following LocalScript placed inside the PIN frame: -- Script settings local len = 4 -- replace this as needed... local regen = false -- determines whether PIN will regenerate after a failed attempt local regmes = "Enter PIN..." -- start message of PIN pad local badmes = "Wrong PIN!" -- message displayed when PIN is wrong local success = "Correct PIN!" -- message displayed when PIN is right -- Script workings local pin = script.Parent local top = pin.Top local txt = top.Numbers local nums = top.NumKeys local pin local stpin local nms txt.Text = regmes local see = game:GetStorage("ReplicatedStorage").PINActivate local function activate() if pin.Visible then pin.Visible = false for _, btn in pairs(nums:GetChildren()) do btn.Active = false end return else pin.Visible = true for _, btn in pairs(nums:GetChildren()) do btn.Active = true end return end end local function rand() math.randomseed(os.time) -- better random numbers this way return tostring(math.floor(math.random(0,9.9))) end local function gen() nms = {rand()} for i=2, len, 1 do nms[#nms+1]=rand() end stpin = nms[1] for i=2, #nms, 1 do stpin = stpin..nms[i] end pin = tonumber(stpin) -- converts the number string into an actual number end gen() local function activate(str) if tonumber(str) ~= pin then txt.Text = badmes wait(2) txt.Text = regmes if regen then gen() wait(0.1) end return else txt.Text = success wait(2) activate() -- insert code here... end end for _, btn in pairs(nums:GetChildren()) do btn.Activated:Connect(function() if txt.Text == "Wrong PIN!" then return end txt.Text = txt.Text..btn.Text if string.len(txt.Text) >= len then activate(txt.Text) end wait(0.1) end) end see.OnClientEvent:Connect(activate) And in a Script put this: local Players = game:GetService("Players") local see = game:GetService("ReplicatedStorage").PINActivate local plr -- replace Event with something like Part.Touched Event:Connect(function(part) if part.Parent.Head then plr = Players:GetPlayerFromCharacter(part.Parent) see:FireClient(plr) end end) What this will do is bring up a ScreenGui for only that player so they can enter the PIN, and they can close it as well. You can modify as needed; have a great day! :D
There is an easier way, try this First, Create a GUI in StarterGui, then, Create a textbox and postion it, after that, create a local script inside and type this. local Password = math.random(1000, 9999) print(Password) game.ReplicatedStorage.Password.Value = Password script.Parent.FocusLost:Connect(function(enter) if enter then if script.Parent.Text == tostring(Password) then print("Correct!") script.Parent.BorderColor3 = Color3.new(0, 255, 0) Password = math.random(1000, 9999) game.ReplicatedStorage.Correct1:FireServer() print(Password) game.ReplicatedStorage.Password.Value = Password else print("wrong!") print(script.Parent.Text) script.Parent.BorderColor3 = Color3.new(255, 0, 0) end end end) That's all in the textbox. Or if you want a random username script, create a textlabel, then, create a local script in the textlabel and type in this. local UserText = script.Parent local Username = math.random(1,10) while true do if Username == 1 then UserText.Text = "John" elseif Username == 2 then UserText.Text = "Thomas" elseif Username == 3 then UserText.Text = "Raymond" elseif Username == 4 then UserText.Text = "Ray" elseif Username == 5 then UserText.Text = "Tom" elseif Username == 6 then UserText.Text = "Kai" elseif Username == 7 then UserText.Text = "Lloyd" elseif Username == 8 then UserText.Text = "Jay" elseif Username == 9 then UserText.Text = "User" else UserText.Text = "Guest" end wait() end All of those if statments are checking what username has been chosen. I have made a roblox game like this recently, so I just took all the script from the game. If you want to check out my game, Click Here
Remove nTh record from array using loop [closed]
Closed. This question needs debugging details. It is not currently accepting answers. Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question. Closed 6 years ago. Improve this question I'm writing a program that reads a .csv file, and then loops through it removing every 10th record it encounters before outputting it. I've been stuck on what I believe is a syntax issue for a while now and just can't seem to nail it. Anyone mind having a look? lines = [] i = 0 elements = [] element2 = [] output = [] file = File.open("./properties.csv", "r") while (line = file.gets) i += 1 # use split to break array up using commas arr = line.split(',') elements.push({ id: arr[0], streetAddress: arr[1], town: arr[2], valuationDate: arr[3], value: arr[4] }) end file.close # filter out blanks and nill rows x = elements.select { |elements| elements[:id].to_i >= 0.1} # Loop to remove every 10th record e = 0 d = 1 loop do x.length if e == (10 * d) d ++ e ++ else x = elements.select[e] e ++ end puts x puts "#{x.length} house in list, #{d} records skipped." CSV FILE ID,Street address,Town,Valuation date,Value 1,1 Northburn RD,WANAKA,1/1/2015,280000 2,1 Mount Ida PL,WANAKA,1/1/2015,280000 3,1 Mount Linton AVE,WANAKA,1/1/2015,780000 4,1 Kamahi ST,WANAKA,1/1/2015,155000 5,1 Kapuka LANE,WANAKA,1/1/2015,149000 6,1 Mohua MEWS,WANAKA,1/1/2015,560000 7,1 Kakapo CT,WANAKA,1/1/2015,430000 8,1 Mt Gold PL,WANAKA,1/1/2015,1260000 9,1 Penrith Park DR,WANAKA,1/1/2015,1250000 10,1 ATHERTON PL,WANAKA,1/1/2015,650000 11,1 WAIMANA PL,WANAKA,1/1/2015,780000 12,1 ROTO PL,WANAKA,1/1/2015,1470000 13,1 Toms WAY,WANAKA,1/1/2015,2230000 14,1 MULBERRY LANE,WANAKA,1/1/2015,415000 15,1 Range View PL,WANAKA,1/1/2015,300000 16,1 Clearview ST,WANAKA,1/1/2015,1230000 17,1 Clutha PL,WANAKA,1/1/2015,700000 18,1 Centre CRES,WANAKA,1/1/2015,295000 19,1 Valley CRES,WANAKA,1/1/2015,790000 20,1 Edgewood PL,WANAKA,1/1/2015,365000 21,1 HUNTER CRES,WANAKA,1/1/2015,335000 22,1 KOWHAI DR,WANAKA,1/1/2015,480000 23,1 RIMU LANE,WANAKA,1/1/2015,465000 24,1 CHERRY CT,WANAKA,1/1/2015,495000 25,1 COLLINS ST,WANAKA,1/1/2015,520000 26,1 AUBREY RD,WANAKA,1/1/2015,985000 27,1 EELY POINT RD,WANAKA,1/1/2015,560000 28,1 LINDSAY PL,WANAKA,1/1/2015,385000 29,1 WINDERS ST,WANAKA,1/1/2015,760000 30,1 Manuka CRES,WANAKA,1/1/2015,510000 31,1 WILEY RD,WANAKA,1/1/2015,420000 32,1 Baker GR,WANAKA,1/1/2015,820000 33,1 Briar Bank DR,WANAKA,1/1/2015,1260000 34,1 LAKESIDE RD,WANAKA,1/1/2015,440000 35,1 PLANTATION RD,WANAKA,1/1/2015,345000 36,1 Allenby PL,WANAKA,1/1/2015,640000 37,1 ROB ROY LANE,WANAKA,1/1/2015,380000 38,1 Ansted PL,WANAKA,1/1/2015,590000 39,1 Fastness CRES,WANAKA,1/1/2015,640000 40,1 APOLLO PL,WANAKA,1/1/2015,385000 41,1 AEOLUS PL,WANAKA,1/1/2015,370000 42,1 Peak View RDGE,WANAKA,1/1/2015,1750000 43,1 Moncrieff PL,WANAKA,1/1/2015,530000 44,1 Islington PL,WANAKA,1/1/2015,190000 45,1 Hidden Hills DR,WANAKA,1/1/2015,1280000 46,1 Weatherall CL,WANAKA,1/1/2015,425000 47,1 Terranova PL,WANAKA,1/1/2015,900000 48,1 Cliff Wilson ST,WANAKA,1/1/2015,1200000 49,1 TOTARA TCE,WANAKA,1/1/2015,460000 50,1 Koru WAY,WANAKA,1/1/2015,570000 51,1 Bovett PL,Wanaka,1/1/2015,495000 52,1 Pearce PL,Wanaka,1/1/2015,675000 53,1 Ironside DR,WANAKA,1/1/2015,570000 54,1 Bob Lee PL,WANAKA,1/1/2015,610000 55,1 Hogan LANE,WANAKA,1/1/2015,395000 56,1 ARDMORE ST,WANAKA,1/1/2015,1190000 57,1 Bullock Creek LANE,WANAKA,1/1/2015,11125000 58,1 DUNMORE ST,WANAKA,1/1/2015,1300000 59,1 Primary LANE,WANAKA,1/1/2015,430000 60,1 SYCAMORE PL,WANAKA,1/1/2015,720000 61,1 FAULKS TCE,WANAKA,1/1/2015,780000 62,1 Alpha CL,WANAKA,1/1/2015,500000 63,1 Coromandel ST,WANAKA,1/1/2015,530000 64,1 Niger ST,WANAKA,1/1/2015,475000 65,1 Maggies Way,WANAKA,1/1/2015,375000 66,1 Hollyhock LANE,QUEENSTOWN,1/1/2015,1080000 67,1 ELDERBERRY CRES,WANAKA,1/1/2015,1340000 68,1 Foxglove HTS,WANAKA,1/1/2015,2520000 69,1 MEADOWSTONE DR,WANAKA,1/1/2015,650000 70,1 OAKWOOD PL,WANAKA,1/1/2015,580000 71,1 MEADOWBROOK PL,WANAKA,1/1/2015,645000 72,1 Jessies CRES,WANAKA,1/1/2015,320000 73,1 Lansdown ST,WANAKA,1/1/2015,700000 74,1 Stonebrook DR,WANAKA,1/1/2015,640000 75,1 Hyland ST,WANAKA,1/1/2015,500000 76,1 TAPLEY PADDOCK,WANAKA,1/1/2015,720000 77,1 Homestead CL,WANAKA,1/1/2015,1750000 78,1 NORMAN TCE,WANAKA,1/1/2015,620000 79,1 Sunrise Bay DR,WANAKA,1/1/2015,3000000 80,1 LARCH PL,WANAKA,1/1/2015,570000 81,1 MILL END,WANAKA,1/1/2015,600000 82,1 Bills WAY,WANAKA,1/1/2015,750000 83,1 Heuchan LANE,WANAKA,1/1/2015,610000 84,1 SARGOOD DR,WANAKA,1/1/2015,455000 85,1 Frederick ST,WANAKA,1/1/2015,455000 86,1 Connell TCE,WANAKA,1/1/2015,600000 87,1 Soho ST,QUEENSTOWN,1/1/2015,320000 88,1 Hikuwai DR,ALBERT TOWN,1/1/2015,280000 89,1 Harrier LANE,WANAKA,1/1/2015,1000000 90,1 Ewing PL,WANAKA,1/1/2015,780000 91,1 Sherwin AVE,ALBERT TOWN,1/1/2015,440000 92,1 Hardie PL,WANAKA,1/1/2015,830000 93,1 Finch ST,ALBERT TOWN,1/1/2015,540000 94,1 Poppy LANE,ALBERT TOWN,1/1/2015,395000 95,1 Warbler LANE,ALBERT TOWN,1/1/2015,410000 96,1 Balneaves LANE,WANAKA,1/1/2015,250000 97,1 Mill Green,Arrowtown,1/1/2015,800000
require 'csv' elements = {} CSV.foreach("properties.csv", :headers => true, :header_converters => :symbol) do |row| elements[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])] end d = 0 e = 0 elements.delete_if do |key, value| e += 1 if e == 10 e = 0 d += 1 end e == 0 end puts "#{elements.length} house in list, #{d} records skipped." At the end of this, elements will have every 10th row removed, and d contains the number of rows removed.
Ruby driver tests failing for credit card with luhn algorithm
I worked up a working code to check if a credit card is valid using luhn algorithm: class CreditCard def initialize(num) ##num_arr = num.to_s.split("") raise ArgumentError.new("Please enter exactly 16 digits for the credit card number.") if ##num_arr.length != 16 #num = num end def check_card final_ans = 0 i = 0 while i < ##num_arr.length (i % 2 == 0) ? ans = (##num_arr[i].to_i * 2) : ans = ##num_arr[i].to_i if ans > 9 tens = ans / 10 ones = ans % 10 ans = tens + ones end final_ans += ans i += 1 end final_ans % 10 == 0 ? true : false end end However, when I create driver test codes to check for it, it doesn't work: card_1 = CreditCard.new(4563960122001999) card_2 = CreditCard.new(4563960122001991) p card_1.check_card p card_2.check_card I've been playing around with the code, and I noticed that the driver code works if I do this: card_1 = CreditCard.new(4563960122001999) p card_1.check_card card_2 = CreditCard.new(4563960122001991) p card_2.check_card I tried to research before posting on why this is happening. Logically, I don't see why the first driver codes wouldn't work. Can someone please assist me as to why this is happening? Thanks in advance!!!
You are using a class variable that starts with ##, which is shared among all instances of CreditCard as well as the class (and other related classes). Therefore, the value will be overwritten every time you create a new instance or apply check_card to some instance. In your first example, the class variable will hold the result for the last application of the method, and hence will reflect the result for the last instance (card_2).
Radix sort not working in Lua
Firstly I should mention I've not been coding very long at all, although that much is probably obvious from my code :P I'm having two problems, firstly the sort isn't functioning correctly but does sort the numbers by their length. Any help here would be appreciated. Secondly it's changing both the table it grabs and the table it returns (not sure why). How do I prevent it changing the table it grabs? I'd prefer if people didn't post a fully optisimised premade code as I'm not going to learn or understand anything that way. function radix_sort(x) pass, bucket, maxstring = 0, x, 2 while true do pass = pass + 1 queue = {} for n=#bucket,1,-1 do key_length = string.len(bucket[n]) key = bucket[n] if pass == 1 and key_length > maxstring then maxstring = key_length end if key_length == pass then pool = string.sub(key, 1,1) if queue[pool + 1] == nil then queue[pool + 1] = {} end table.insert(queue[pool + 1], key) table.remove(bucket, n) end end for k,v in pairs(queue) do for n=1,#v do table.insert(bucket, v[n]) end end if pass == maxstring then break end end return bucket end
There's a lot of changes I made to get this working, so hopefully you can look through and pickup on them. I tried to comment as best I could. function radix_sort(x) pass, maxstring = 0, 0 -- to avoid overwriting x, copy into bucket like this -- it also gives the chance to init maxstring bucket={} for n=1,#x,1 do -- since we can, convert all entries to strings for string functions below bucket[n]=tostring(x[n]) key_length = string.len(bucket[n]) if key_length > maxstring then maxstring = key_length end end -- not a fan of "while true ... break" when we can set a condition here while pass <= maxstring do pass = pass + 1 -- init both queue and all queue entries so ipairs doesn't skip anything below queue = {} for n=1,10,1 do queue[n] = {} end -- go through bucket entries in order for an LSD radix sort for n=1,#bucket,1 do key_length = string.len(bucket[n]) key = bucket[n] -- for string.sub, start at end of string (LSD sort) with -pass if key_length >= pass then pool = tonumber(string.sub(key, pass*-1, pass*-1)) else pool = 0 end -- add to appropriate queue, but no need to remove from bucket, reset it below table.insert(queue[pool + 1], key) end -- empty out the bucket and reset, use ipairs to call queues in order bucket={} for k,v in ipairs(queue) do for n=1,#v do table.insert(bucket, v[n]) end end end return bucket end Here's a test run: > input={55,2,123,1,42,9999,6,666,999,543,13} > output=radix_sort(input) > for k,v in pairs(output) do > print (k , " = " , v) > end 1 = 1 2 = 2 3 = 6 4 = 13 5 = 42 6 = 55 7 = 123 8 = 543 9 = 666 10 = 999 11 = 9999
pool = string.sub(key, 1,1) always looks at the first character; perhaps you meant string.sub(key, pass, 1)