Related
I write a multiplayer game(snake) with backend based on Ruby. This function must receive commands for frontend and send the current state of the game. But throw NoMethod error on the four line of my function for the changeside method and I don't know why because of that class method is present.
Class method example
def changeside(nump,newSide)
opp = {'R':'L','U':'D','D':'U','L':'R'}
cx = {'L':-1,'R':1,'U':0,'D':0}
cx = {'L':0,'R':0,'U':-1,'D':1}
if newSide!=opposite[players[nump]['side']] && ['R','L','U','D'].count( newSide)==1
players[nump]['side']['cx'] = cx[newSide]
players[nump]['side']['cy'] = cy[newSide]
end
end
Error example
2020-10-07 18:01:23 - NoMethodError - undefined method `[]' for nil:NilClass:
The function I'm run
def getStatus(game)
ans = {"opStatus"=>TRUE}
puts game
$games[game['gid'.to_i]]['game'].changeside(2,game['side'])
$games[game['gid'.to_i]]['game'].move(($games[game['gid']]['fid']==game['pid']?1:2))
ans["gameStatus"] = $games[game['id']]['game'].run
ans['timer'] = $games[game['id']]['game'].timer
ans['snake'] = $games[game['id']][($games[game['id']]['fid']==game['pid']?1:2)].snake
ans['enemy'] = $games[game['id']][($games[game['id']]['fid']==game['pid']?2:1)].snake
ans['food'] = $games[game['id']]['game'].food
end
Here is JSON sent to the function
{"gid"=>"1", "side"=>"R", "pid"=>"1"}
To fix that, I debugged that moment, but I couldn't go inside a class method.
Here is the full code of the class game.
It located in another file and called by
`require_relative 'game.rb'`
Full code of the class.
class Game
attr_accessor :players, :food, :walls, :timer, :run,:winner
def initialize()
#players = {}
#winner = -1
#players[1] = {'snake'=>[[9,2],[8,2],[7,2]]}
#players[1]['cx'] = 0
#players[1]['cy'] = -1
#players[1]['side'] = 'U'
#players[2] = {'snake'=>[[2,9],[2,8],[2,7]]}
#players[2]['cx'] = -1
#players[2]['cy'] = 0
#players[2]['side'] = 'L'
#timer = 0
#run = FALSE
genFood
end
def genFood()
#food = [rand(10)+1,rand(10)+1]
while players[1]['snake'].include?(food) || players[2]['snake'].include?(food)
#food = [rand(10)+1,rand(10)+1]
end
end
def move(nump)
if #run
#timer+=0.25
#players[nump]['snake'].shift
#players[nump]['snake'].push([#players[id]['snake'][0]+#players[id]['cx'],#players[id]['snake'][1]+#players[id]['cy']])
if #players[nump]['snake'][0] == food
#players[nump]['snake'][0].unshift(food)
#food = [rand(10)+1,rand(10)+1]
while players[nump]['snake'].include(food) or players[1]['snake'].include(food)
#food = [rand(10)+1,rand(10)+1]
end
end
if #player[nump]['snake'].count(#player[nump]['snake'][-1])==2 ||
#winner = ((nump==1)?2:1)
elsif #players[((nump==1)?2:1)]['snake'].count(#player[nump]['snake'][-1])==1
#winner = 0
else
if #timer==60
if #players[1]['snake'].length()>#players[2]['snake'].length()
#winner = 1
elsif #players[1]['snake'].length()<#players[2]['snake'].length()
winner = 2
else
winner = 0
end
end
end
end
end
def changeside(nump,newSide)
opp = {'R':'L','U':'D','D':'U','L':'R'}
cx = {'L':-1,'R':1,'U':0,'D':0}
cx = {'L':0,'R':0,'U':-1,'D':1}
if newSide!=opposite[players[nump]['side']] && ['R','L','U','D'].count( newSide)==1
players[nump]['side']['cx'] = cx[newSide]
players[nump]['side']['cy'] = cy[newSide]
end
end
end
1.how should i keep-alive?
2.How to calculate the response time?
I rewrote loust according to online blog
class WebSocketClient(object):
def __init__(self, host):
self.host = host
self.ws = websocket.WebSocket()
def connect(self, burl, name):
start_time = time.time()
try:
self.conn = self.ws.connect(url=burl)
except websocket.WebSocketTimeoutException as e:
total_time = int((time.time() - start_time) * 1000)
events.request_failure.fire(request_type="websocket", name=name+"_error", response_time=total_time, exception=e)
flag = False
return flag
else:
total_time = int((time.time() - start_time) * 1000)
events.request_success.fire(request_type="websocket", name=name+"_right", response_time=total_time, response_length=0)
return self.conn
def recv(self):
return self.ws.recv()
def send(self, msg):
self.ws.send(msg)
def close(self):
self.ws.close()
class WebsocketLocust(Locust):
def __init__(self, *args, **kwargs):
super(WebsocketLocust, self).__init__(*args, **kwargs)
self.client = WebSocketClient(self.host)
class SearchTest(TaskSet):
#task
def searchtest(self):
self.url = 'wss://api.bbxapp.vip/v1/ifcontract/realTime'
self.client.connect(self.url, name='chat_room')
flag = True
while flag:
data ={"action":"ping"}
data =json.dumps(data)
self.client.send(data)
globals = {'true': 0}
recv = self.client.recv()
recv=json.loads(recv)
if recv["data"]== "pong":
self.client.send(data)
else:
flag = False
Output:
Name # reqs # fails Avg Min Max | Median req/s
------------------------------------------------------------------------------------
chat_room_right 1 0(0.00%) 3089 3089 3089 | 3100 0.00
------------------------------------------------------------------------------------
Total 1 0(0.00%) 0.00
the avg time is so long,I think that "total_time = int((time.time() - start_time) * 1000)" have a few mistakes.
please help me
import random
from tkinter import *
class Spinner(object):
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def getPosition(self):
return self.position
def getName(self):
return self.name
def spin(self):
newSpin = Spinner.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
class Path(object):
#staticmethod
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(9)]
ladders[0][0] = 2
ladders[0][1] = 9
ladders[1][0] = 8
ladders[1][1] = 11
return ladders
#staticmethod
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(10)]
chutes[0][0] = 9
chutes[0][1] = 3
chutes[1][0] = 12
chutes[1][1] = 6
return chutes
class Check(Player):
def __init__(self):
super(Check,self).__init__()
def checkLadders(self):
ladders = Path.buildLadders()
for i in range(0,len(ladders),1):
if self.getPosition() == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def newPosition(self):
return self.position
def checkChutes(self):
chutes = Path.buildChutes()
for i in range(0,len(chutes),1):
if self.getPosition() == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes!")
class Match_Position(Player):
def __init__(self,name):
super(Match_Position,self).__init__(name)
self.match = [[70,235],
[180,235],
[290,235],
[400, 235],
[400, 140],
[290, 140],
[180, 140],
[70, 140],
[70, 45],
[180, 45],
[290, 45],
[400, 45]]
self.name = name
self.players = Player(self.name)
self.pos = self.players.getPosition()
self.position_actual = []
self.__str__()
self.actualpos()
def __str__(self):
for j in range(len(self.match)):
if self.pos == (j+1):
self.position_actual.append(self.match[j][0])
self.position_actual.append(self.match[j][1])
def actualpos(self):
return self.position_actual
class Display(object):
def __init__(self,master,img,name):
canvas_width = 650
canvas_height = 300
self.name = name
print(self.name)
self.pos = Match_Position(self.name).actualpos()
print(self.pos)
self.canvas = Canvas(master, width = canvas_width, height = canvas_height, bg = "yellow")
self.canvas.grid(padx=0, pady=0)
self.canvas.create_image(300,150,anchor=CENTER, image = img)
self.animate(master)
def animate(self,master):
Button(master, text= "ROLL", command=self.say_hello(self.name[0])).grid( row=3, column=0, sticky=E)
Button(master, text= "ROLL", command=self.say_hello1(self.name[1])).grid( row=3, column=1, sticky=E)
def say_hello(self,name):
self.name = name
self.name = Player(self.name)
self.name.spin()
Check.checkLadders(self.name)
Check.checkChutes(self.name)
x = self.pos[0]
y = self.pos[1]
self.canvas.create_oval(x,y,x+20,y+20, fill='blue')
def say_hello1(self,name):
self.name = name
self.name = Player(self.name)
self.name.spin()
Check.checkLadders(self.name)
Check.checkChutes(self.name)
x = self.pos[0]
y = self.pos[1]
self.canvas.create_oval(x,y,x+20,y+20, fill='red')
class BounceController(object):
def __init__(self):
master = Tk()
master.title("Snake and Ladder")
master.geometry("700x350")
img = PhotoImage( file = "puzzlor-chutes-and-ladders.gif" )
name = ['n','s']
Display(master,img,name).animate(master)
master.mainloop()
def main():
BounceController()
main()
It printed out this, but the error:
"'Player' object does not support indexing" pop out.
What is object does not support indexing error is?
And when I click the button, the oval does not actually move.
And using tkinter Button, I can call the method, right?
But by doing so, if I want to make for example, clicking the button, result to the oval moving to different location, how do I achieve that? Since as my code, above, the oval does not move eventhough the button is clicked.
Thanks. Since I'm quite new to python and programming, any help would be such a gratitude.
Indexing is when you suffix an object with [n], where n is an int. Here is how to reproduce the message.
>>> class C: pass
>>> C()[1]
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
C()[1]
TypeError: 'C' object does not support indexing
The File entry above the error message tells you the line number and expression that gave the error. Someplace in your code, as indicated by the traceback you did not show us, you have x[n], where x in an instance of the Player class you defined.
An object is subscriptable if and only if it has a __getitem__ method, which Player does not have and should not have.
I created a Class and created many instances and stored it into an array called messages
If I type,
print messages[0]
It gives
#<SMSMessage:0x00000001681d88 #id=29185, #account_id=1565, #upload_id=0, #txaction_type_id=9, #txid=0, #finanalytics_txid=1565,
#date_posted=2015-05-13 17:58:01 +0530, #sequence=1, #sic_code=0,
#amount=-1802.0, #raw_name="MERLINS", #filtered_name="MERLINS",
#cleaned_name="NULL", #merchant_id="NULL", #memo="NULL",
#check_num="NULL", #ref_num="NULL", #balance=0.0, #created_at=2015-05-13 18:03:30 +0530,
#updated_at=2015-05-13 18:08:17 +0530, #status="0", #tagged=0, #merged_with_txaction_id=0, #note="NULL", #usd_amount=0.0, #attachment_ids="NULL", #automatch=0, #merchant_name="MERLINS", #tag_names=nil, #transfer_txaction_id=0, #fi_date_posted=2015-05-13 17:58:01 +0530, #transaction_status_id=0, #mc_code="NULL", #provider_txn_type="NULL", #latitude=19.09686, #longitude=72.8537753, #sync_status=31, #sec_account_id=0, #associated_sms_id=130672, #account_key="YzI5ZDUyNWY5NmYwNWFiNjJiYmE1YTk4Y2VkYTBjYTZmOGM5ZTI0NzE2MzU2MzAwMmU2OWU2MzNiYmQ2YTZhMA==", #id_on_client=229, #sync_delete_status=0,
#matching_bill_id=0, #mapped_account_number=0, #additional_description="NULL", #category_id=45, #data_processing_flag=4,
#derived_description="NULL", #final_description="NULL", #derived_merchant="Merlins Bar", #final_merchant="NULL",
#tentative_location_flag=-1, #tentative_latitude="-90.00000000000", #tentative_longitude="-90.00000000000", #mongo_merchant_id="102", #parent_category_id=40, #raw_description="NULL", #formatted_description="NULL", #associated_sms_client_id=779, #account_client_id=4>
If i try to access the ID by typing,
print messages[0].id
It gives me an error
NoMethodError: undefined method `id' for #<SMSMessage:0x00000001681d88>
How do I resolve this ?
PS - The SMSMessage Class Code is
class SMSMessage
def initialize(id,account_id,upload_id,txaction_type_id,txid,finanalytics_txid,date_posted,sequence,sic_code,amount,raw_name,filtered_name,cleaned_name,merchant_id,memo,check_num,ref_num,balance,created_at,updated_at,status,tagged,merged_with_txaction_id,note,usd_amount,attachment_ids,automatch,merchant_name,tag_names,transfer_txaction_id,fi_date_posted,transaction_status_id,mc_code,provider_txn_type,latitude,longitude,sync_status,sec_account_id,associated_sms_id,account_key,id_on_client,sync_delete_status,matching_bill_id,mapped_account_number,additional_description,category_id,data_processing_flag,derived_description,final_description,derived_merchant,final_merchant,tentative_location_flag,tentative_latitude,tentative_longitude,mongo_merchant_id,parent_category_id,raw_description,formatted_description,associated_sms_client_id,account_client_id)
#id = id.to_i
#account_id = account_id.to_i
#upload_id = upload_id.to_i
#txaction_type_id = txaction_type_id.to_i
#txid = txid.to_i
#finanalytics_txid = finanalytics_txid.to_i
#date_posted = Time.parse(date_posted)
#sequence = sequence.to_i
#sic_code = sic_code.to_i
#amount = amount.to_f
#raw_name = raw_name
#filtered_name = filtered_name
#cleaned_name = cleaned_name
#merchant_id = merchant_id
#memo = memo
#check_num = check_num
#ref_num = ref_num
#balance = balance.to_f
#created_at = Time.parse(created_at)
#updated_at = Time.parse(updated_at)
#status = status
#tagged = tagged.to_i
#merged_with_txaction_id = merged_with_txaction_id.to_i
#note = note
#usd_amount = usd_amount.to_f
#attachment_ids = attachment_ids
#automatch = automatch.to_i
#merchant_name = merchant_name
#tag_names = tag_names
#transfer_txaction_id = transfer_txaction_id.to_i
#fi_date_posted = Time.parse(fi_date_posted)
#transaction_status_id = transaction_status_id.to_i
#mc_code = mc_code
#provider_txn_type = provider_txn_type
#latitude = latitude.to_f
#longitude = longitude.to_f
#sync_status = sync_status.to_i
#sec_account_id = sec_account_id.to_i
#associated_sms_id = associated_sms_id.to_i
#account_key = account_key
#id_on_client = id_on_client.to_i
#sync_delete_status = sync_delete_status.to_i
#matching_bill_id = matching_bill_id.to_i
#mapped_account_number = mapped_account_number.to_i
#additional_description = additional_description
#category_id = category_id.to_i
#data_processing_flag = data_processing_flag.to_i
#derived_description = derived_description
#final_description = final_description
#derived_merchant = derived_merchant
#final_merchant = final_merchant
#tentative_location_flag = tentative_location_flag.to_i
#tentative_latitude = tentative_latitude.to_f
#tentative_longitude = tentative_longitude.to_f
#mongo_merchant_id = mongo_merchant_id
#parent_category_id = parent_category_id.to_i
#raw_description = raw_description
#formatted_description = formatted_description
#associated_sms_client_id = associated_sms_client_id.to_i
#account_client_id = account_client_id.to_i
end
end
Since you do not define accessor methods for object attributes, you should use instance_variable_get:
messages[0].instance_variable_get(:#id)
To be able to read id attribute (that is messages[0].id) you would want to add
attr_reader :id
to your model. If you will need to write this attribute, you would define attr_writer :id.
For both (read and write) there is a attr_accessor :id.
I'm trying to make a little class in ruby allowing me to make a system tray icon and use the notification balloons. But I'm having problems using structs with Win32API calls.
http://www.ruby-forum.com/topic/18102
Shell_NotifyIcon Function
NOTIFYICONDATA Struct
Heres the code I have now, all it does is add an icon to the system tray:
require 'Win32API'
NIF_MESSAGE = 1
NIF_ICON = 2
NIF_TIP = 4
NIF_STATE = 8
NIF_INFO = 10
NIM_ADD = 0
NIM_MODIFY = 1
NIM_DELETE = 2
NIS_HIDDEN = 1
NIS_SHAREDICON = 2
class NotifyIconData < Struct.new(:cbsize, :hwnd, :uid, :uflags, :ucallbackmessage, :hicon)#, :sztip, :dwstate, :dwstatemask, :szinfo, :utimeout, :uversion, :szinfotitle, :dwinfoflags, :guiditem, :hballoonicon)
def pack
values.pack('LLIIIL')
end
# def self.unpack(s)
# new(*s.unpack('LLIIIL'))
# end
end
#===---
ExtractIcon = Win32API.new('shell32', 'ExtractIcon', 'LPI', 'L')
Shell_NotifyIcon = Win32API.new('shell32', 'Shell_NotifyIconA', 'LP', 'I')
hicoY = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM32\INETCPL.CPL', 21) # Green tick
hicoN = ExtractIcon.call(0, 'C:\WINDOWS\SYSTEM32\INETCPL.CPL', 22) # Red minus
#===---
tiptxt = "hai"
nid = NotifyIconData.new
nid.cbsize = Marshal.dump(NotifyIconData).size#6*4+64
nid.hwnd = 0
nid.uid = 'ruby'.hash
nid.uflags = NIF_INFO
nid.ucallbackmessage = 0
nid.hicon = hicoY
ret = Shell_NotifyIcon.call( NIM_ADD, nid.pack << tiptxt << "\0"*(64 - tiptxt.size) )
p 'Err: NIM_ADD' if ret == 0
sleep(3) # <----<<
# pnid = [6*4+64, 0, 'ruby'.hash, NIF_ICON | NIF_TIP, 0, hicoN].pack('LLIIIL') << tiptxt << "\0"*(64 - tiptxt.size)
# ret = Shell_NotifyIcon.call(NIM_MODIFY, pnid)
# p 'Err: NIM_MODIFY' if ret == 0
# sleep(6) # <----<<
nid.uflags = 0
ret = Shell_NotifyIcon.call( NIM_DELETE, nid.pack << "\0" )
p 'Err: NIM_DELETE' if ret == 0
Check out visualuruby and its demo/example files. They got me some balloons quite readily.