Related
for school i am making an assignment, implementing astar search with the use of dictionaries. I have been trying a few things, but now i am stuck. in my first iteration the if statement if f_next < f: is true, so why does it not break out of the loop. It immediately goes to the else statement so my closed list contains both values from the if and else statement, how can i fix this. I have provided my code, some assignment information and the input below.
Given a grid-like graph, find the shortest path using A* between the two nodes with the maximum weight. Use the Euclidean as heuristic function, which is calculated between two points in a coordinate system (x1,y1) and (x2,y2) as follows:
d = p(x2 −x1)2 + (y2 −y1)2 (1) where, the nodes of the graph are represented as such points (see the input format below). You can assume that there exists a path between the two nodes with the maximum weight, and that all nodes have a unique weight.
Data format 1. The following is the input format expected by the algorithm for Task 1.
The program takes as input a list of nodes, represented as points in a coordinate system (e.g.,(x1,y1) and their weights separated by a ;.
In a new line the data-set of the graph edges are given following the pattern ”source node (xs,ys), end node (xe,ye), edge cost; ...”.
(x1), (y1), (weight1); ...(xn), (yn), (weightn);\n
(x1), (y1), (x2), (y2), (edgecost1); ...(xs), (ys), (xe), (ye), (edgecostm);\n
The expected output is the path from the start to the end node.
(xstart), (ystart)->(xi), (yi)...->(xend), (yend)\n
Input:
0, 0, 193; 0, 1, 146; 0, 2, 121; 0, 3, 174; 0, 4, 144; 1, 0, 191; 1, 1, 123; 1, 2, 151; 1, 3, 126; 1, 4, 163; 2, 0, 182; 2, 1, 107; 2, 2, 109; 2, 3, 125; 2, 4, 165; 3, 0, 169; 3, 1, 149; 3, 2, 180; 3, 3, 199; 3, 4, 199; 4, 0, 160; 4, 1, 148; 4, 2, 123; 4, 3, 197; 4, 4, 156
0, 0, 1, 0, 1; 0, 0, 0, 1, 1; 0, 1, 1, 1, 1; 0, 1, 0, 2, 1; 0, 2, 1, 2, 1; 0, 2, 0, 3, 1; 0, 3, 1, 3, 1; 0, 3, 0, 4, 1; 0, 4, 1, 4, 1; 1, 0, 2, 0, 1; 1, 0, 1, 1, 1; 1, 1, 2, 1, 1; 1, 1, 1, 2, 1; 1, 2, 2, 2, 1; 1, 2, 1, 3, 1; 1, 3, 2, 3, 1; 1, 3, 1, 4, 1; 1, 4, 2, 4, 1; 2, 0, 3, 0, 1; 2, 0, 2, 1, 1; 2, 1, 3, 1, 1; 2, 1, 2, 2, 1; 2, 2, 3, 2, 1; 2, 2, 2, 3, 1; 2, 3, 3, 3, 1; 2, 3, 2, 4, 1; 2, 4, 3, 4, 1; 3, 0, 4, 0, 1; 3, 0, 3, 1, 1; 3, 1, 4, 1, 1; 3, 1, 3, 2, 1; 3, 2, 4, 2, 1; 3, 2, 3, 3, 1; 3, 3, 4, 3, 1; 3, 3, 3, 4, 1; 3, 4, 4, 4, 1
I am trying to find a path between (0,0) and (3,4)
import collections
import math
import sys
class Graph:
"""Class to represent a Graph, as a list of weighted nodes and edges."""
def __init__(self):
"""Function to initialize a Graph object"""
self.node_g = {}
self.edge_g = collections.defaultdict(list)
pass
def add_node(self, node_id, weight):
"""Function to add a node to a Graph object."""
self.node_g[node_id] = weight
print(self.node_g)
pass
def add_edge(self, source_id, end_id, weight):
weightedge = (end_id, weight)
self.edge_g[source_id].append(weightedge)
pass
def __repr__(self):
return "nodes:% s edges:% s" % (self.node_g, self.edge_g)
def __str__(self):
return "From str method of graph: nodes are % s, " \
"edges are % s" % (self.node_g, self.edge_g)
def build_Graph(nodes, edges):
"""Function to build a grid-like Graph object from the input data.
Parameters
----------
nodes : list of nodes, each represented as coordinates, and node_weight.
For example: x1, y1, weight; x2, y2, weight; ...
edges : list of edges, each represented as source and end node coordintates, and edge_weight.
For example: x1, y1, x2, y2, weight; x3, y3, x4, y4, weight; ...
Return
----------
A Graph object.
"""
G = Graph()
for n in nodes:
aux = n.split(', ')
temp1 = int(aux[0])
temp2 = int(aux[1])
temp_node = (temp1, temp2)
G.add_node(temp_node, weight=int(aux[2]))
for e in edges:
aux = e.split(', ')
temp1 = int(aux[0])
temp2 = int(aux[1])
temp = (temp1, temp2)
auxn1 = int(aux[2])
auxn2 = int(aux[3])
auxn = (auxn1, auxn2)
G.add_edge(temp, auxn, weight=int(aux[4]))
return G
def print_output(nodes):
"""Function to print the shortest path between the two nodes with the highest weigths.
Parameters
----------
nodes : list of list of nodes (represented as: tuples of coordinates).
"""
# nodes = [x1, y1, x2, y2, x3, y3]
# Expected output: x1, y1->x2, y2->x3, y3
def astar_shortest_path(G, source_id, end_id, heuristic):
"""Function to return the shortest path between two nodes in a Graph"""
open_set = [source_id]
#print(open_set)
closed_set = []
g = 0
h = heuristic(source_id, end_id)
f = g + h
#print(G.edge_g[open_set[0]][0])
#print(G.edge_g[source_id])
#print(G.edge_g[end_id])
while len(open_set) > 0:
if source_id == end_id:
return closed_set
for index, item in enumerate(G.edge_g[open_set[0]]):
print(item)
var = item[0]
print(var)
if not index:
next = item[0]
g_next = item[1]
h_next = heuristic(item[0], end_id)
f_next = h_next + g_next
if f_next < f:
f += f_next
h += h_next
g += g_next
open_set.append(next)
print(open_set)
closed_set.append(open_set[0])
print(closed_set)
open_set.remove(open_set[0])
print(open_set)
else:
next_2 = item[0]
g_next_2 = item[1]
h_next_2 = heuristic(item[0], end_id)
f_next_2 = g_next_2 + h_next_2
if f_next_2 < f:
f += f_next_2
h += h_next_2
g += g_next_2
closed_set.append(open_set[0])
print(closed_set)
open_set.remove(open_set[0])
print(open_set)
open_set.append(next_2)
print(open_set)
#print(open_set)
def heuristic(a, b):
#print(a, b)
"""Function to compute the Euclidean distance between two nodes."""
dx = abs(b[0] - a[0]) ** 2
#print(dx)
dy = abs(b[1] - a[1]) ** 2
#print(dy)
return math.sqrt(dx + dy)
if __name__ == '__main__':
# Read the input
# The first line is made of a list of nodes, written as tuples of cartesian coordinates.
# For example: x1, y1, weight; x2, y2, weight; ...
# In the previous example, x1, y1, weight; is the first node
nodes = input().split('; ')
# The second line is made of edges, written as source and end node coordinates, and edge_weight.
# For example: x1, y1, x2, y2, weight; x3, y3, x4, y4, weight; ...
# In the previous example, x1, y1, x2, y2, weight; is the first edge
edges = input().split('; ')
# Build a grid graph from the input nodes and edges
G = build_Graph(nodes, edges)
print(G)
sort_edge = sorted(G.node_g, key=G.node_g.get)
max1 = sort_edge[-2]
#print(max1)
max2 = sort_edge[-1]
#print(max2)
# Find the two nodes with the highest weights in the graph
source_id = (0, 0) #max1
end_id = (3, 4) #max2
# Compute the path between the two nodes with the highest weight
# The source node is the one with the highest weigth
# You are free to customize the following function
s_path = astar_shortest_path(G, source_id, end_id, heuristic)
# Expected output format: list of lists of nodes (represented as: tuples of coordinates).
# For example: x1, y1->x2, y2->x3, y3
print_output(s_path)
#############
hi when i made my fragment shader coding i use:
---fragment
$HEADER$
void main(void)
{
float width = 0.0;
float offset = 0.1;
vec4 out_color = vec4(0, 0, 1, 1);
float coord = normalize(gl_FragCoord.x);
if (width == 0.0) {
vec4 out_color = vec4(0, 1, 1, 1);
}
else if (mod(((coord+offset) / width),2.0) < 0.3) {
vec4 out_color = vec4(0, 0, 0, 1);
}
gl_FragColor = out_color;
}
but when running the file with the vertex shader:
---vertex
$HEADER$
void main(void)
{
vec4 pos = vec4(vPosition.xy, 0.0, 1.0);
gl_Position = projection_mat * modelview_mat * pos;
}
and the python code:
from kivy.app import App
from kivy.base import EventLoop
from kivy.graphics import Mesh
from kivy.graphics.instructions import RenderContext
from kivy.uix.widget import Widged
w = 1000
h = 600
class GlslDemo(Widget):
def __init__(self, **kwargs):
Widget.__init__(self, **kwargs)
self.canvas = RenderContext(use_parent_projection=True)
self.canvas.shader.source = 'basic.glsl'
fmt = (
(b'vPosition', 2, 'float'),
)
vertices = (
0, 0,
w, 0,
w, h,
0, h,
)
indices = (0, 1, 2, 2, 3, 0)
with self.canvas:
Mesh(fmt=fmt, mode='triangles',
indices=indices, vertices=vertices)
class GlslApp(App):
def build(self):
EventLoop.ensure_window()
return GlslDemo()
if __name__ == '__main__':
GlslApp().run()
The problem when running this file is that it just outputs the vec4 out_color and skips the if and if else statements of the fragment shader code.
The variable out_color is declared 3 times in the fragment shader
1st in the scope of main
vec4 out_color = vec4(0, 0, 1, 1);
And another 2 times in the if statement:
if (width == 0.0) {
vec4 out_color = vec4(0, 1, 1, 1);
}
else if (mod(((coord+offset) / width),2.0) < 0.3) {
vec4 out_color = vec4(0, 0, 0, 1);
}
You have to assign to the variable which is declared in the scope of main, instead of declaring new variables in the if statement:
vec4 out_color = vec4(0, 0, 1, 1);
if (width == 0.0) {
out_color = vec4(0, 1, 1, 1);
}
else if (mod(((coord+offset) / width),2.0) < 0.3) {
out_color = vec4(0, 0, 0, 1);
}
Note, vec4 out_color; is a variable declaration, So vec4 out_color = vec4(0, 1, 1, 1); is an assignment to a new variabel, while out_color = vec4(0, 1, 1, 1); would assign to the existing variable out_color.
Below is a mininal reproducer:
GL_CHECK(glClearColor(0.4f, 0.4f, 0.4f, 1.0f));
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT));
GL_CHECK(glUseProgram(this->pp_->shader_program));
GL_CHECK(glEnable(GL_TEXTURE_2D));
GL_CHECK(glActiveTexture(GL_TEXTURE0));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, this->particle_->id));
GLfloat points[] = { 150.f, 150.f, 10.0f, 150.0f, 175.0f, 10.0f };
GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };
shader_pass_set_uniform(this->pp_, HASH("mvp"), glm::value_ptr(this->camera_));
GL_CHECK(glEnableVertexAttribArray(0));
GL_CHECK(glEnableVertexAttribArray(3));
GL_CHECK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, &points[0]));
GL_CHECK(glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, &colors[0]));
GL_CHECK(glDrawArrays(GL_POINTS, 0, 2));
vertex shader:
#version 300 es
layout(location = 0) in highp vec3 vertex;
layout(location = 3) in highp vec4 color;
out lowp vec4 vcolor;
uniform mat4 mvp;
void main()
{
vcolor = color;
gl_Position = mvp * vec4(vertex.xy, 0.0, 1.0);
gl_PointSize = vertex.z;
}
fragment shader:
#version 300 es
uniform sampler2D stexture;
in lowp vec4 vcolor;
layout(location = 0) out lowp vec4 ocolor;
void main()
{
ocolor = texture(stexture, gl_PointCoord) * vcolor;
}
Nothing gets rendered on-screen, my glxinfo can be found in this pastebin. When I render the same texture onto a triangle it works.
Here is also the render loop as captured with apitrace:
250155 glClearColor(red = 0.5, green = 0.5, blue = 0.5, alpha = 1)
250157 glClear(mask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
250159 glUseProgram(program = 9)
250161 glEnable(cap = GL_TEXTURE_2D)
250163 glActiveTexture(texture = GL_TEXTURE0)
250165 glBindTexture(target = GL_TEXTURE_2D, texture = 2)
250167 glUniformMatrix4fv(location = 0, count = 1, transpose = GL_FALSE, value = {0.001953125, 0, 0, 0, 0, 0.002604167, 0, 0, 0, 0, -1, 0, -1, -1, -0, 1})
250168 glEnableVertexAttribArray(index = 0)
250170 glEnableVertexAttribArray(index = 3)
250174 glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_FALSE, stride = 0, pointer = blob(24))
250175 glVertexAttribPointer(index = 3, size = 4, type = GL_FLOAT, normalized = GL_FALSE, stride = 0, pointer = blob(32))
250176 glDrawArrays(mode = GL_POINTS, first = 0, count = 2)
250178 glXSwapBuffers(dpy = 0x1564010, drawable = 50331661)
I guess that could mean, that the range of point sizes, that your GLES implementation supports, may be not what you are expecting. You can try something like:
GLint range[2];
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, range); // for example, (1, 511) in my implementation
to check it out. Any implementation guarantees, that range[1] is at least 1.0. The value gl_PointSize is getting clamped to the range, so in the worst case you won't be able to set point with size, greater than 1. In this case gl_PointCoord seems to evaluate to (1, 0) (according to formula from specs) at the only fragment, that is going to be drawn for each point. After the texture's wrap mode come into play, (1, 0) may turn into (0, 0), for example if you are using GL_REPEAT as the texture's wrap mode. If you'd like to safely draw a point with side, greater than one, you should try using the ordinary way to draw squares (for example using four vertices and GL_TRIANGLE_FAN or GL_TRIANGLE_STRIP mode).
http://www.mediafire.com/view/z8ad4pedqr7twbl/donut.png
I want to draw this donut like that image. I have use raphaeljs for draw it. But I can't find the solution to make these borders with red and blue. Can someone help me? Is it possible or not?
My code below:
Raphael.fn.donutChart = function (cx, cy, r, rin, values, labels, stroke) {
var paper = this,
rad = Math.PI / 180,
chart = this.set();
function sector(cx, cy, r, startAngle, endAngle, params) {
//console.log(params.fill);
var x1 = cx + r * Math.cos(-startAngle * rad),
x2 = cx + r * Math.cos(-endAngle * rad),
y1 = cy + r * Math.sin(-startAngle * rad),
y2 = cy + r * Math.sin(-endAngle * rad),
xx1 = cx + rin * Math.cos(-startAngle * rad),
xx2 = cx + rin * Math.cos(-endAngle * rad),
yy1 = cy + rin * Math.sin(-startAngle * rad),
yy2 = cy + rin * Math.sin(-endAngle * rad);
return paper.path(["M", xx1, yy1,
"L", x1, y1,
"A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2,
"L", xx2, yy2,
"A", rin, rin, 0, +(endAngle - startAngle > 180), 1, xx1, yy1, "z"]
).attr(params);
}
var angle = 0,
total = 0,
start = 0,
process = function (j) {
var value = values[j],
angleplus = 360 * value / total,
popangle = angle + (angleplus / 2),
color = Raphael.hsb(start, .75, 1),
ms = 500,
delta = 30,
bcolor = "#ccc",
p = sector(cx, cy, r, angle, angle + angleplus, {fill:"#dfdfdf", "stroke-width":3, stroke:"red"}),
txt = paper.text(cx + (r + delta + 155) * Math.cos(-popangle * rad), cy + (r + delta + 150) * Math.sin(-popangle * rad), labels[j]).attr({fill:"#000", stroke: "none", opacity: 0, "font-size": 20});
p.mouseover(function () {
p.stop().animate({transform: "s1.25 1.25 " + cx + " " + cy}, ms, "elastic");
txt.stop().animate({opacity: 1}, ms, "elastic");
}).mouseout(function () {
p.stop().animate({transform: ""}, ms, "elastic");
txt.stop().animate({opacity: 0}, ms);
});
angle += angleplus;
chart.push(p);
chart.push(txt);
start += .1;
};
for (var i = 0, ii = values.length; i < ii; i++) {
total += values[i];
}
for (i = 0; i < ii; i++) {
process(i);
}
return chart;
};
var values = [],
labels = [];
$("tr").each(function () {
values.push(parseInt($("td", this).text(), 10));
labels.push($("th", this).text());
});
$("table").hide();
Raphael("holder", 700, 700).donutChart(350, 350, 80, 150, values, labels, "#fff");
You have to create separate paths if you want to stroke them differently:
var p = paper.path(["M", xx1, yy1,
"L", x1, y1,
"A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2,
"L", xx2, yy2,
"A", rin, rin, 0, +(endAngle - startAngle > 180), 1, xx1, yy1, "z"]
).attr(params);
paper.path(["M", x1, y1, "A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2]).attr({stroke: 'blue', 'stroke-width': 3});
paper.path(["M", xx2, yy2, "A", rin, rin, 0, +(endAngle - startAngle > 180), 1, xx1, yy1]).attr({stroke: 'red', 'stroke-width': 3});
return p;
I'd like to create a Draughts' game board.
At first, Everything worked fine while I was drawing squares and pawns directly on the "board" canvas. As I have to manipulate those pawns afterward, I wanted it to be more explicite by creating each square and pawn as objects.
So I tried to create a Board which will contain black or white square which will contain circles (the pawns). Then everything, messed up. I don't know why. Even so it looks perfectly logical (for me).
I think it is related to the use of the pack method.
Here's the code :
from tkinter import *
class Parent(Tk):
def getRoot(self):
return(self.body)
def setTitle(self,title):
self.title(title)
def run(self):
self.mainloop()
class Drawing:
def __init__(self,root,width,height):
self.zone=Canvas(root, width=width, height=height)
def put(self,root,row,col):
self.zone.grid(root,row=row,column=col)
def getDrawing(self):
return(self.zone)
def rectangle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_rectangle(coordX1,coordY1,coordX2,coordY2,fill=color, outline="black")
def circle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_oval(coordX1,coordY1,coordX2,coordY2,fill=color,outline="black")
if __name__=="__main__":
root=Parent()
root.setTitle("Draughts")
board=Drawing(root,400,400)
size=40
logicBoard=[[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
DIMENSION=10
for i in range(DIMENSION):
for j in range(DIMENSION):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
if(not(i%2==j%2)):#if the square is black (on the board)
color="black"
else:
color="white"
case=Drawing(board.getDrawing(),40,40)
case.rectangle(coordX1,coordY1,coordX2,coordY2,color)
case.getDrawing().pack()
if(logicBoard[i][j]>0):
pawnColor="white"
elif(logicBoard[i][j]<0):
pawnColor="black"
if (not(i%2==j%2)):
pawn=Drawing(case.getDrawing(),40,40)
pawn.circle(0,0,30,30,pawnColor)
pawn.getDrawing().pack()
board.getDrawing().pack()
root.run()
Thank you !
EDIT:
This is what I get :
The problem is that you create a new Canvas and call pack() on it in each iteration, instead of using the one you create at the beginning. In the end, you are using the class Drawing to create new Drawings. I suggest you to use only one class to represent all the board, with the methods to draw the squares and the circles.
I've changed the colors of the ovals to have a better contrast:
from tkinter import Tk, Canvas
from itertools import product
class Board(Tk):
def __init__(self, width, height, cellsize):
Tk.__init__(self)
self.cellsize = cellsize
self.canvas = Canvas(self, width=width, height=height)
self.canvas.bind("<Button-1>", self.onclick)
self.canvas.pack()
def draw_rectangle(self, x1, y1, x2, y2, color):
self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="black")
def draw_circle(self, x1, y1, x2, y2, color):
self.canvas.create_oval(x1, y1, x2, y2, fill=color, outline="black")
def onclick(self, event):
i = int(event.x / self.cellsize)
j = int(event.y / self.cellsize)
print "You clicked on cell (%s, %s)" % (i, j)
if __name__=="__main__":
size = 40
board = Board(400, 400, size)
board.title("Draughts")
logicBoard = [[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
for (i, j) in product(range(10), range(10)):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
color = "white" if i%2 == j%2 else "black"
board.draw_rectangle(coordX1, coordY1, coordX2, coordY2, color)
cell = logicBoard[i][j]
if cell != 0:
pawnColor = "red" if cell > 0 else "blue"
board.draw_circle(coordX1, coordY1, coordX2, coordY2, pawnColor)
board.mainloop()
Edit:
If you want to keep track of the clicks, it is clearer and simpler to bind a handler function to the canvas and calculate the point, instead of creating lots of canvas with their own event handler.