This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
TechnicallyMay's profile picture

Program Can't Assign Variables to Strings Properly

Started by TechnicallyMay, 26 January 2018 - 12:56 AM
TechnicallyMay #1
Posted 26 January 2018 - 01:56 AM
Hey, so I'm super new to computercraft and coding as a general rule, so understand that this code will definitely have some issues. I know it can be done more efficiently, and that's part of why I'm here! So - I'm implementing a currency on my direwolf20 1.7.10 server, and I'm writing a code that will keep track of the value of player's "banks". So I finally got it working, the only problem is that if two players have the same amount of currency in their banks (counted by a different program), it will display one of the two players names twice. Any help and advice would be very much appreciated. Thank you!


x = (0)
mon = peripheral.wrap("left")
mod = peripheral.wrap("back")
win = window.create(mon, 1, 1, 20, 1)
smi = {"SMI", x}
mit = {"Mitch", x}
mac = {"Mac", x}
jos = {"Josh", x}
mad = {"Madi", x}

--Functions
local function sortInfo()
   table.sort(balRank)
   table.insert(balInfo, 1, balRank[5])
   table.insert(balInfo, 2, balRank[4])
   table.insert(balInfo, 3, balRank[3])
   table.insert(balInfo, 4, balRank[2])
   table.insert(balInfo, 5, balRank[1])
end
local function dispBal()

  balRank = {smi[2], mit[2], mac[2], jos[2], mad[2]} -- values
  balNames = {"SMI", "Mitchell", "Mac", "Josh", "Madi"}
  balInfo = {}   -- sorted
  term.redirect(mon)
  mon.setTextScale(2)
  mon.setBackgroundColor(colors.lightBlue)
  mon.setTextColor(colors.white)
  mon.clear()
  win.redraw()
  mon.setCursorPos(3, 1)
  mon.setTextColor(colors.blue)
  mon.setCursorPos(1, 4)


	  sortInfo()
	    for k, v in pairs(balInfo) do
			  for i = 1, 5 do
	    if balInfo[i] == smi[2] then
		    term.clearLine()
			  term.setCursorPos(1, (i + 2))
		  print(i..":"..balNames[1]..">	  "..balInfo[i])
		
		   elseif balInfo[i] == mit[2] then
		    term.clearLine()
			    term.setCursorPos(1, (i + 2))
		   print(i..":"..balNames[2].."> "..balInfo[i])
			
		    elseif balInfo[i] == mac[2] then
			    term.clearLine()
			    term.setCursorPos(1, (i + 2))
			 print(i..":"..balNames[3]..">	  "..balInfo[i])
			  
			 elseif balInfo[i] == jos[2] then
				    term.clearLine()
			    term.setCursorPos(1, (i + 2))
			   print(i..":"..balNames[4]..">	 "..balInfo[i])
				
				 elseif balInfo[i] == mad[2] then
				    term.clearLine()
				    term.setCursorPos(1, (i + 2))
				   print(i..":"..balNames[5]..">	 "..balInfo[i])
					
				    else return
			  end
			 end
		    end
		   end 
-- "Mason eat'a the poo-poo"
	  
local function getBal()
  while true do
local balRec eV, sR, sC, rC, msg
  = os.pullEvent("modem_message")
if sC == 1 then
  smi[2] = msg
   elseif sC == 2 then
	 mit[2] = msg
	  elseif sC == 3 then
	   mac[2] = msg
		 elseif sC == 4 then
		   jos[2] = msg
		    elseif sC == 5 then
			  mad[2] = msg
				 else
				   print("Error, unknown channel")
	 end
	 dispBal()
  end
end

-- Program
  for i = 1, 5 do
    mod.open(i)
   end
  win.setBackgroundColor(colors.green)
  win.clear()
  win.setTextColor(colors.yellow)
  win.write("Leaderboard")
while true do
getBal()
end

Everything works fine except for the stated issue. I know I have some unnecessary tables.. the issue would be a problem with the "dispBal()" function.
KingofGamesYami #2
Posted 26 January 2018 - 03:21 AM
The formatting! It burns my eyes!
Spoiler

x = (0)
mon = peripheral.wrap("left")
mod = peripheral.wrap("back")
win = window.create(mon, 1, 1, 20, 1)
smi = {"SMI", x}
mit = {"Mitch", x}
mac = {"Mac", x}
jos = {"Josh", x}
mad = {"Madi", x}

--Functions
local function sortInfo()
  table.sort(balRank)
  table.insert(balInfo, 1, balRank[5])
  table.insert(balInfo, 2, balRank[4])
  table.insert(balInfo, 3, balRank[3])
  table.insert(balInfo, 4, balRank[2])
  table.insert(balInfo, 5, balRank[1])
end

local function dispBal()
  balRank = {smi[2], mit[2], mac[2], jos[2], mad[2]} -- values
  balNames = {"SMI", "Mitchell", "Mac", "Josh", "Madi"}
  balInfo = {}   -- sorted
  term.redirect(mon)
  mon.setTextScale(2)
  mon.setBackgroundColor(colors.lightBlue)
  mon.setTextColor(colors.white)
  mon.clear()
  win.redraw()
  mon.setCursorPos(3, 1)
  mon.setTextColor(colors.blue)
  mon.setCursorPos(1, 4)


  sortInfo()
  for k, v in pairs(balInfo) do
    for i = 1, 5 do
      if balInfo[i] == smi[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[1]..">   "..balInfo[i])

      elseif balInfo[i] == mit[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[2].."> "..balInfo[i])

      elseif balInfo[i] == mac[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[3]..">    "..balInfo[i])

      elseif balInfo[i] == jos[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[4]..">         "..balInfo[i])

      elseif balInfo[i] == mad[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[5]..">         "..balInfo[i])

      else
        return
      end
    end
  end
end 
-- "Mason eat'a the poo-poo"

local function getBal()
  while true do
    local balRec eV, sR, sC, rC, msg = os.pullEvent("modem_message")
    if sC == 1 then
      smi[2] = msg
    elseif sC == 2 then
      mit[2] = msg
    elseif sC == 3 then
      mac[2] = msg
    elseif sC == 4 then
      jos[2] = msg
    elseif sC == 5 then
      mad[2] = msg
    else
      print("Error, unknown channel")
    end
    dispBal()
  end
end

-- Program
for i = 1, 5 do
  mod.open(i)
end

win.setBackgroundColor(colors.green)
win.clear()
win.setTextColor(colors.yellow)
win.write("Leaderboard")

while true do
  getBal()
end
I haven't modified your code besides fixing some whitespace issues that were staring me in the face. Feel free to ask about any specific changes.
I also haven't been able to really track down the issue you're talking about. Considering the name doesn't appear to be tied to the balance, that's rather confusing.
Edited on 26 January 2018 - 02:22 AM
TechnicallyMay #3
Posted 26 January 2018 - 09:04 PM
Hey you rock, thank you!! So the issue is, when it goes through and checks the balInfo to each players balance, it just goes through a bunch of if - then statements. So if two players have the same balance it will assign both values to the name that comes first in the if-then sequence.
KingofGamesYami #4
Posted 27 January 2018 - 01:01 AM
I assume the problem is this bit of code then?


  for k, v in pairs(balInfo) do
    for i = 1, 5 do
      if balInfo[i] == smi[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[1]..">   "..balInfo[i])

      elseif balInfo[i] == mit[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[2].."> "..balInfo[i])

      elseif balInfo[i] == mac[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[3]..">    "..balInfo[i])

      elseif balInfo[i] == jos[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[4]..">         "..balInfo[i])

      elseif balInfo[i] == mad[2] then
        term.clearLine()
        term.setCursorPos(1, (i + 2))
        print(i..":"..balNames[5]..">         "..balInfo[i])

      else
        return
      end
    end

May I recommend an alternative data structure?


--# demonstrate declaration
local tBalances = {
  {name="my name", balance = 100}
  {name="your name", balance = 99}
}
--# demonstrate adding a balance
table.insert( tBalances, {name="someone", balance=105} )
--# demonstrate displaying balances
for k, v in in pairs( tBalances ) do
  print( v.name .. "> " .. v.balance )
end
--# demonstrate sorting
table.sort( tBalances, function( a, b ) return a.balance < b.balance end )
--# demonstrate displayinig sorted
for k, v in pairs( tBalances ) do
  print( k .. ":" .. v.name .. "> " .. v.balance )
end
TechnicallyMay #5
Posted 27 January 2018 - 01:05 AM
I'll try it out when I get home and let you know. Thank you so much for your time!
TechnicallyMay #6
Posted 27 January 2018 - 05:32 PM
It works perfectly, except that it lists the first two tables I write in tBalances on the leaderboard. I'm at work so I can't show you the exact code currently, but I wrote a few lines that remove those two from the table before printing it. I'm sure that's not the best way to do it though is it? I'm just not sure how to tell it to sort the table the way I want it when each of the balances are variables that are constantly changing without defining two balances myself.
KingofGamesYami #7
Posted 27 January 2018 - 05:47 PM
If you take a look at table.sort, you'll notice there is a second argument, a function. Said function compares a and b, I wrote a simple one which applies the default table.sort behavior, but based on the balance amount.
TechnicallyMay #8
Posted 28 January 2018 - 04:46 AM
Ahh I took your recommendations too literally. I was having a hard time understanding table.sort. But I went through my code and removed most of the inefficiencies that I could find, and this is the final result:

mon = peripheral.wrap("left")
mod = peripheral.wrap("back")
win = window.create(mon, 1, 1, 20, 1)
win2 = window.create(mon, 1, 1, 2, 1)
win3 = window.create(mon, 19, 1, 20, 1)
balVal = {0, 0, 0, 0, 0}
--Functions
local function dispBal()
local balInfo = {
{name = "SMI  ", bal = balVal[1]},
{name = "Mitch", bal = balVal[2]},
{name = "Mac  ", bal = balVal[3]},
{name = "Josh ", bal = balVal[4]},
{name = "Madi ", bal = balVal[5]}
}
  term.clear()
  win.redraw()
  win2.redraw()
  win3.redraw()
  term.setCursorPos(1, 3)
  term.setTextColor(colors.blue)
  term.setBackgroundColor(colors.lightBlue)
  table.sort(balInfo, function(a, B)/> return a.bal > b.bal end)
  
for k, v in pairs(balInfo) do
  print(k..": "..v.name.."> "..v.bal)
  end
end
local function getBal()
  while true do
    eV, sR, sC, rC, msg = os.pullEvent("modem_message")
    for i = 1, 5 do
	  if sC == i then
	    balVal[i] = msg
	  end
    dispBal()
    end
  end
end
-- Program
for i = 1, 5 do
  mod.open(i)
end
  term.redirect(mon)
  mon.setTextScale(2)
  term.clear()
  term.setCursorPos(1, 3)
  win.setBackgroundColor(colors.blue)
  win.clear()
  win.setTextColor(colors.yellow)
  win.setCursorPos(5, 1)
  win.write("Leaderboard")
  win2.setBackgroundColor(colors.red)
  win2.clear()
  win3.setBackgroundColor(colors.red)
  win3.clear()
while true do
  getBal()
end

Thank you so much for your help, you really are awesome. :)/>