Package: tankwar-env
Installationpip install tankwar-envorgit clone https://github.com/khoda81/tankwar.git
cd tankwar
pip install -eorpipinstallgit+https://github.com/khoda81/tankwar.gitKeyboardEnvironment:Esc: setenv.donetoTrue(end episode on next step)F: toggle limited frame rateHumanAgent:WASD: movementQE: rotate turretSpace: toggle shootingLeft Mouse Button: start shooting when pressed and stop shooting when releasedScript:G: toggle window update (disabling window update will blur window and increase performance)Basic Usageimportpygamefromtankwar.agentsimportHumanAgent,RandomAgentfromtankwar.envsimportTankWarEnvdefmain():random_agents=2# create environmentenv=TankWarEnv(random_agents+1,shape=(200,200))# create agentsagents=[HumanAgent(env)]+[RandomAgent(env)for_inrange(random_agents)]# initialize a window with the height of 200# width is calculated based on env.shape# limit frame rate to 60 if a human is playingenv.init_window(600,True)done=False# reset environmentobservations=env.reset()display_to_human=TruewhileTrue:ifdisplay_to_human:env.render("human")# render to screenelse:# if render is not called window events are not processed either# so, manually processing window eventsenv.process_window_events()actions=[agent.act((None,None),0,done)foragentinagents]observations,rewards,done,info=env.step(actions,print_fps=True)# if g is pressed screen is toggled# disabling screen will make rendering faster# because copying frame to window takes timeforeventinenv.events:ifevent.type==pygame.KEYDOWNandevent.key==pygame.K_g:display_to_human=notdisplay_to_humanifnotdisplay_to_human:env.blur_window()ifdone:breakif__name__=="__main__":main()Main Usageimporttimeimportpygameimporttorchfromtorch.nn.functionalimportinterpolatefromtqdmimporttqdmfromtankwar.agentsimportHumanAgent,RandomAgentfromtankwar.envsimportTankWarEnvMAX_EPISODE_STEPS=5000defmain():random_agents=2human_agent=False# whether or not a human is currently playingdisplay_to_human=human_agent# create environmentenv=TankWarEnv(random_agents+human_agent,shape=(200,200))w,h=env.shape# create agentsagents=([HumanAgent(env)]*human_agent+[RandomAgent(env)for_inrange(random_agents)])# initialize a window with the height of 200# width is calculated based on env.shape# limit frame rate to 60 if a human is playingenv.init_window(h,human_agent)padded_frame=torch.zeros(3,w+200,h+200)observations=env.reset()done=Falserewards=[0]*env.ns=time.time()for_intqdm(range(MAX_EPISODE_STEPS),unit="step"):# render to screenifdisplay_to_human:env.render("human")# convert frame to pytorch tensor with shape (3, height, width)# frames are cached and will be rendered once per stepframe=env.render("rgb_array")frame_torch=(torch.from_numpy(frame)/255).permute(2,0,1)# each frame will be down sampled to (w, h)ifenv.window_scale!=1:frame_torch=interpolate(frame_torch.reshape(1,*frame_torch.shape),(h,w))[0]# with 100 pixels padding on each side:padded_frame[:,100:-100,100:-100]=frame_torch# image that each agent can seeimages=[]fori,tankinenumerate(env.tanks):x,y=tank.body.position.int_tupleimages.append(padded_frame[:,y:y+200,x:x+200])actions=[agent.act((observation,image),reward,done)foragent,observation,image,rewardinzip(agents,observations,images,rewards)]observations,rewards,done,info=env.step(actions)# if g is pressed screen is toggled# disabling screen will make rendering faster# because copying frame to window takes timeforeventinenv.events:ifevent.type==pygame.KEYDOWNandevent.key==pygame.K_g:display_to_human=notdisplay_to_humanifnotdisplay_to_human:env.blur_window()ifdone:breakprint(f"Episode took{time.time()-s:.2f}seconds.")if__name__=="__main__":main()