I am trying to get all solutions for a Mixed Integer program through ortools. I have two lists x and y of size 4. I want to get all solutions which satisfy sum(x) = 4 * sum(y). I created a function which takes list of past solutions as input and returns next solution. I am able to get only 2 solutions even though there are more. What am I doing wrong here?
I am expecting the following solutions
Solution 1:
xs1 = [0,0,0,0], ys1 = [0,0,0,0]
Solution 2:
xs2 = [4,0,0,0], ys2 = [1,0,0,0]
Solution 3:
xs3 = [0,4,0,0], ys3 = [1,0,0,0]
Solution 4:
xs4 = [0,0,4,0], ys4 = [0,0,1,0]
and soon on
from ortools.linear_solver import pywraplp
def opt(xs, ys):
solver = pywraplp.Solver.CreateSolver('SCIP')
infinity = solver.infinity()
# x and y are integer non-negative variables.
n = 4
M = 20
x = [0]* n
y = [0]* n
w = [[0]* n]*len(xs)
δ = [[0]* n]*len(xs)
for i in range(0,n):
x[i] = solver.IntVar(0, 20, 'x'+str(i))
y[i] = solver.IntVar(0, 20, 'y'+str(i))
for j in range(len(xs)):
w[j][i] = solver.IntVar(0, 20, 'zp'+str(j)+ '-' + str(i))
δ[j][i] = solver.IntVar(0, 1, 'δ'+str(j)+ '-' + str(i))
for j in (range(len(xs))):
for i in range(0,n):
solver.Add((w[j][i] - x[i] + xs[j][i]) >=0)
solver.Add((w[j][i] - x[i] + xs[j][i]) <= M*(1-δ[j][i]))
solver.Add((w[j][i] + x[i] - xs[j][i]) >=0)
solver.Add((w[j][i] + x[i] - xs[j][i]) <= M*δ[j][i])
for j in range(len(xs)):
solver.Add(solver.Sum([w[j][i] for i in range(0,n)]) >= 1)
solver.Add(solver.Sum([x[i] for i in range(0, n)]) - 4 * solver.Sum([y[i] for i in range(0, n)]) == 0)
solver.Minimize(solver.Sum([x[i] for i in range(0, n)]))
status = solver.Solve()
if status == pywraplp.Solver.OPTIMAL:
solver_x = [0]*n
solver_y = [0]*n
for i in range(0,n):
solver_x[i] = x[i].solution_value()
solver_y[i] = y[i].solution_value()
return ([solver_x, solver_y, solver.Objective().Value()])
else:
print('No Solution')
return ([[0], [0]], -1)
psx = [[0,0,0,0], [0,4,0,0]]
psy = [[0,0,0,0], [1,0,0,0]]
ns = opt(psx, psy)
print(ns)
Output:
No Solution
([[0], [0]], -1)
Reference:
Finding multiple solutions to general integer linear programs
How to write constraints for sum of absolutes
If you have a pure integer programming model, you can use the CP-SAT solver which allows you to print all the solutions [See this].
This question already has answers here:
Is it possible to implement gradual movement of an object to given coordinates in Pygame?
(1 answer)
How to make a circle move diagonally from corner to corner in pygame
(1 answer)
How to move the object in squared path repeatedly?
(1 answer)
Closed 5 months ago.
Currently i'm making Space invaders, and I'm having trouble making the aliens move properly from to the side and down the screen. The aliens are supposed to move one direction, then once they hit the edge of the screen they're meant to go down the screen a little bit, then change direction, and repeat this until they get to the bottom of the screen where the player is. So far this is what I have as a part of my code...
for element in smallInvaders:
element.move_ip(dx,dy)
for element in smallInvaders:
if element.bottom > 100:
dy = 0
dx = 1
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in medInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in medInvaders:
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in bigInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in bigInvaders:
if element.right >= width or element.left <= 0 :
dy += 0.5
dx = 0
invaderDirSwapped = True
Essentially, smallInvaders, medInvaders and bigInvaders are all lists, where each object in the list is a rect object, that act as the aliens. I tried to make it so that I change the direction y value (dy) when the aliens touch the side of the screen (they're originally moving to the left as dx is -1, and dy is 0 initially), then the dy value gets put to 0, when the y value of the aliens hits a specific amount, but this doesn't seem to work, as the next time through when the aliens go from right to left, they either get stuck, or phase off the side of the screen. I understand both if statements are being executed at the same time, but i'm stuck on what to do because of it, and if there are any other solutions towards fixing the problem.
here's my full code...
import pygame
import sys
import time
import random
#initialize pygame
pygame.mixer.init()
pygame.init()
width = 800
height = 600
# set the size for the surface (screen)
screen = pygame.display.set_mode((width, height),pygame.FULLSCREEN)
width = screen.get_width()
height = screen.get_height()
print(width)
print(height)
# set the caption for the screen
pygame.display.set_caption("Space Invaders")
score = 0
def checkCollision(missles, type, score, invader_kill):
for missle in missles:
collision = missle.collidelist((type))
if collision > -1:
type.pop(collision)
invader_kill.play()
missles.remove(missle)
missle.move_ip(0,missleSpeed)
pygame.draw.rect(screen, WHITE, missle,0)
# define colours you will be using
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0,0,0)
YELLOW = (255,255,0)
shoot_sound = pygame.mixer.Sound("Music-sfx/shoot.wav")
invader_kill = pygame.mixer.Sound("Music-sfx/invaderkilled.wav")
ship_kill = pygame.mixer.Sound("Music-sfx/explosion.wav")
clock = pygame.time.Clock()
FPS = 60
s = 25
#load and scale images
smallInvaderImg = pygame.image.load("images/smallinvader.png")
smallInvaderImg = pygame.transform.scale(smallInvaderImg,(s,s))
medInvaderImg = pygame.image.load("images/crabinvader.png")
medInvaderImg = pygame.transform.scale(medInvaderImg, (s,s))
bigInvaderImg = pygame.image.load("images/biginvader.png")
bigInvaderImg = pygame.transform.scale(bigInvaderImg, (s,s))
shipImg = pygame.image.load("images/ship.png")
shipImg = pygame.transform.scale(shipImg, (60,60))
shieldImg = pygame.image.load("images/shield.png")
shieldImg = pygame.transform.scale(shieldImg , (80,55))
smallInvaders = []
medInvaders = []
bigInvaders = []
enemiesMap = ["sssssssssss",
"mmmmmmmmmmm",
"mmmmmmmmmmm",
"bbbbbbbbbbb"]
invadertype = [smallInvaders,medInvaders,bigInvaders]
dx = -1
dy = 0
x = 240
y = 45
gap = 10
for element in enemiesMap:
for char in element:
if char == "s":
smallInvaders.append(pygame.Rect(x,y,s,s))
elif char == "m":
medInvaders.append(pygame.Rect(x,y,s,s))
elif char == "b":
bigInvaders.append(pygame.Rect(x,y,s,s))
x += s + gap
y += s + gap
x = 240
ship = pygame.Rect(width/2,525,60,60)
shield1 = pygame.Rect(40,370,80,60)
shield2 = pygame.Rect(250,370,80,60)
shield3 = pygame.Rect(460,370,80,60)
shield4 = pygame.Rect(670,370,80,60)
if ship.right == width:
ship.right = width
#missles
maxMissles = 3
missleSpeed = -6
missleWidth = 5
missleHeight = 30
enemmissleWidth = 5
enemmissleHeight = 25
missles = []
missleFired = False
lives = 3
playbutton = pygame.Rect(width/2,height/2,200,90)
playbutton.center = (width/2,height/2)
quitbutton = pygame.Rect(width/2,height/2,200,90)
quitbutton.center = (width/2,height/2+110)
playagn = pygame.Rect(width/2,height/2,235,90)
playagn.center = (width/2,height/2)
playword = pygame.font.Font("pixeltext.ttf", 35)
title = pygame.font.Font("pixeltext.ttf", 80)
quitword = pygame.font.Font("pixeltext.ttf",35)
endscreen = pygame.font.Font("pixeltext.ttf", 90)
playagaintext = pygame.font.Font("pixeltext.ttf", 35)
gameover = pygame.font.Font("pixeltext.ttf",120 )
livestext = pygame.font.Font("pixeltext.ttf",25)
enemMissleFire = False
enemmislist = []
enemymissle = (pygame.Rect(ship.centerx,y,enemmissleWidth,enemmissleHeight))
Cont = False
invaderDirSwapped = False
screenControl = 0
main = True
while main:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
main = False
for element in smallInvaders:
element.move_ip(dx,dy)
for element in smallInvaders:
if element.bottom > 100:
dy = 0
dx = 1
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in medInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in medInvaders:
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in bigInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in bigInvaders:
if element.right >= width or element.left <= 0 :
dy += 0.5
dx = 0
invaderDirSwapped = True
key_input = pygame.key.get_pressed()
if key_input[pygame.K_RIGHT] and ship.right < width:
ship.move_ip(4,0)
if key_input[pygame.K_LEFT] and ship.left > 0:
ship.move_ip(-4,0)
if key_input[pygame.K_SPACE] and not missleFired:
missleFired = True
enemmissleFire = True
shoot_sound.play()
missles.append(pygame.Rect(ship.centerx,ship.top,missleWidth,missleHeight))
if screenControl == 0:
screen.fill(BLACK)
texttitle = title.render("SPACE INVADERS", True, WHITE)
textrect = texttitle.get_rect()
textrect.center = (width/2, 100)
screen.blit(texttitle,textrect)
if playbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playbutton), 0)
if playbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE, (playbutton), 4)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE,(quitbutton), 0)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,quitbutton,4)
textplay = playword.render("PLAY", True, BLUE)
textrect2 = textplay.get_rect()
textrect2.center = (width/2,height/2)
screen.blit(textplay,textrect2)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
if screenControl == 1:
screen.fill(BLACK)
if len(missles) > 0:
if missleFired and missles[-1].bottom < (ship.top - 120) and not key_input[pygame.K_SPACE]:
missleFired = False
if len(missles) == 0:
missleFired = False
for invader in smallInvaders:
screen.blit(smallInvaderImg, invader)
for invader in medInvaders:
screen.blit(medInvaderImg, invader)
for invader in bigInvaders:
screen.blit(bigInvaderImg, invader)
screen.blit(shipImg,ship)
screen.blit(shieldImg,shield1)
screen.blit(shieldImg,shield2)
screen.blit(shieldImg,shield3)
screen.blit(shieldImg,shield4)
allinvaders = [smallInvaders,medInvaders,bigInvaders]
randinvader = random.choice(allinvaders)
if randinvader == smallInvaders:
if len(smallInvaders) >= 1:
abc = random.choice(smallInvaders)
elif randinvader == medInvaders:
if len(medInvaders) >= 1:
abc = random.choice(medInvaders)
elif randinvader == bigInvaders:
if len(bigInvaders) >= 1:
abc = random.choice(bigInvaders)
move and draw missles
enemMissleFire = False
if not enemMissleFire:
if enemymissle.colliderect(ship):
lives -= 1
print(f"Lives: {lives}")
enemymissle.center = (abc.centerx,abc.centery)
time.sleep(0.5)
if enemymissle.top > height:
enemymissle.center = (abc.centerx,abc.centery)
if lives == 0:
ship_kill.play()
screenControl = 3
enemymissle.move_ip(0,-missleSpeed + 1)
pygame.draw.rect(screen, WHITE, enemymissle,0)
liveval = livestext.render(f"Lives: {str(lives)}", True, WHITE)
textlives = liveval.get_rect()
textlives.center = (65,20)
screen.blit(liveval,textlives)
checkCollision(missles,smallInvaders,score,invader_kill)
checkCollision(missles,medInvaders,score,invader_kill)
checkCollision(missles,bigInvaders,score,invader_kill)
if smallInvaders == [] and medInvaders == [] and bigInvaders == []:
screenControl = 2
if screenControl == 2:
screen.fill(BLACK)
if playagn.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
print("GAME START")
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playagn),0)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE, (quitbutton),0)
if playagn.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(playagn), 4)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(quitbutton),4)
textend = endscreen.render("YOU WON!", True, WHITE)
textrect4 = textend.get_rect()
textrect4.center = (width/2, 150)
screen.blit(textend,textrect4)
textplayagn = playagaintext.render("PLAY AGAIN", True, BLUE)
textrect5 = textplayagn.get_rect()
textrect5.center = (width/2,height/2)
screen.blit(textplayagn,textrect5)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
if screenControl == 3:
screen.fill(BLACK)
textgameovr = gameover.render("GAME OVER", True, WHITE)
textrect6 = textgameovr.get_rect()
textrect6.center = (width/2,110)
screen.blit(textgameovr,textrect6)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE, (quitbutton),0)
if playagn.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
print("GAME START")
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playagn),0)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(quitbutton),4)
if playagn.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(playagn), 4)
textplayagn = playagaintext.render("PLAY AGAIN", True, BLUE)
textrect5 = textplayagn.get_rect()
textrect5.center = (width/2,height/2)
screen.blit(textplayagn,textrect5)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
pygame.display.update()
This is my first time coding. I'm doing it as ab elective module. I have to program an ai_player to go from playing randomly to winning and I'm stuck. Any advice would be appreciated. The game is Connect 4. i keep getting "object has no attribute" error.
import random
import time
def board():
for i in range(0, 8, 1):
for j in range(0, 10, 1):
board[i][j] = 0
return board
def move(board, valid_move):
start_time = time.time()
x = 0
while x == 0:
i = range(7, -1, -1)
j = range(0, 10, 1)
first_move = board[i][j]
board[7][4] = 1
if board[i-1][j] == 0: #above
first_move = [i, j]
x = 1
print " valid above"
return j
elif (board[i][j+1] == 0 and (i <= 7 and j <= 9)) or (board[i-1][j+1] == 0 and (i <= 7 and j <= 9)) or (board[i-1][j+1] == 0 and (i <= 7 and j <= 9)): #right
first_move = [i, (j+1)]
x = 1
print " valid right"
return (j+1)
elif board[i][j-1] == 0 or board[i-1][j-1] == 0 or board[i-1][j-1] == 0: #left
first_move = [i, (j-1)]
x = 1
print " valid left"
return (j-1)
else:
r = random.randint(0, 7)
c = random.randint(0, 9)
first_move = [r, c]
x = 1
print " random move"
return c
end_time = time.time() - start_time
print end_time
return first_move
File "F:/5. Fifth year/1st Semester/MPR 213 2016/Project 2016/attempts.py", line 20, in board
board[i][j] = 0
TypeError: 'function' object has no attribute '__getitem__'
It looks like you're trying to create a multidimensional list called board. This is not how you do that though, what you've actually done is created a function called board, and then you try to index that function, which fails since it's not a list.
To create board, use something like
board = [[0] * 10 for i in range(0, 8)]