In this post, we’ll create the game of Tetris as shown in the video above.
Most readers are probably familiar with Tetris – a popular and addictive video game created by Russian software engineer Alexey Pajitnov in 1984.
Let’s look at the parts of the game and the rules.
The game consists of a board that is 10 cells across and 20 cells high as shown below.
Figure 1 : The Tetris board is a 10 x 20 grid of cells.
In Tetris, blocks fall from the top of the board vertically down in chunks of 4. The chunks are called tetrominoes but in this post we will simply call them “tetris pieces.”
In Figure 1, we can see a number of Tetris pieces on the bottom of the board (each colored differently), and one blue colored line piece falling down.
There are seven different kinds of pieces. We denote them using the letters “O”, “I”, “S”, “Z”, “L”, “J”, and “T” in our code.
Figure 2 : Tetris Pieces
The tetris pieces fall from the top to the bottom of the board.
You can move the pieces by pressing keyboard control keys. In this post, we are using the following keys for controlling the motion of the pieces
If you make all the cells in one row full by moving and placing the pieces intelligently as they fall, the full line clears and you get points based on how many lines you clear.
If a single line is cleared by an action, you receive 40 points. If two lines are cleared in one shot, you receive 100 points, and if three lines are cleared you get 300 points.
Figure 3: Tetris line clear example. On the left we show four lines are completely full because of the blue block on the right most column. This state changes to the one shown on the right giving the user a TETRIS or 1200 points.
Clearing 4 lines in a single shot gets you 1200 points! This is called a TETRIS and is the highest score you can get in one shot. This is shown in Figure 3.
Your objective is to score as many points as possible before the pile of tetris pieces grows too high.
Let’s see how we can use OpenCV’s drawing functions and keyboard handler along with numpy to create the game of Tetris.
First, we will import some standard libraries.
import cv2 import numpy as np from random import choice
Now, we will make a board, initialize some other variables, and define the parameter
SPEED to be the speed at which the tetris pieces fall.
SPEED = 1 # Controls the speed of the tetris pieces # Make a board board = np.uint8(np.zeros([20, 10, 3])) # Initialize some variables quit = False place = False drop = False switch = False held_piece = "" flag = 0 score = 0
Tetris pieces can have one of seven different shapes.
# All the tetris pieces next_piece = choice(["O", "I", "S", "Z", "L", "J", "T"])
A new Tetris piece always appears in a specific location on the screen.
Next, we will write a function that
Below we have a function that gets the spawn location and color of a given tetris piece.
def get_info(piece): if piece == "I": coords = np.array([[0, 3], [0, 4], [0, 5], [0, 6]]) color = [255, 155, 15] elif piece == "T": coords = np.array([[1, 3], [1, 4], [1, 5], [0, 4]]) color = [138, 41, 175] elif piece == "L": coords = np.array([[1, 3], [1, 4], [1, 5], [0, 5]]) color = [2, 91, 227] elif piece == "J": coords = np.array([[1, 3], [1, 4], [1, 5], [0, 3]]) color = [198, 65, 33] elif piece == "S": coords = np.array([[1, 5], [1, 4], [0, 3], [0, 4]]) color = [55, 15, 215] elif piece == "Z": coords = np.array([[1, 3], [1, 4], [0, 4], [0, 5]]) color = [1, 177, 89] else: coords = np.array([[0, 4], [0, 5], [1, 4], [1, 5]]) color = [2, 159, 227] return coords, color
Let’s now write a function for displaying the board and capturing keyboard events.
def display(board, coords, color, next_info, held_info, score, SPEED): # Generates the display border = np.uint8(127 - np.zeros([20, 1, 3])) border_ = np.uint8(127 - np.zeros([1, 34, 3])) dummy = board.copy() dummy[coords[:,0], coords[:,1]] = color right = np.uint8(np.zeros([20, 10, 3])) right[next_info[:,0] + 2, next_info[:,1]] = next_info left = np.uint8(np.zeros([20, 10, 3])) left[held_info[:,0] + 2, held_info[:,1]] = held_info dummy = np.concatenate((border, left, border, dummy, border, right, border), 1) dummy = np.concatenate((border_, dummy, border_), 0) dummy = dummy.repeat(20, 0).repeat(20, 1) dummy = cv2.putText(dummy, str(score), (520, 200), cv2.FONT_HERSHEY_DUPLEX, 1, [0, 0, 255], 2) # Instructions for the player dummy = cv2.putText(dummy, "A - move left", (45, 200), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "D - move right", (45, 225), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "S - move down", (45, 250), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "W - hard drop", (45, 275), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "J - rotate left", (45, 300), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "L - rotate right", (45, 325), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) dummy = cv2.putText(dummy, "I - hold", (45, 350), cv2.FONT_HERSHEY_DUPLEX, 0.6, [0, 0, 255]) cv2.imshow("Tetris", dummy) key = cv2.waitKey(int(1000/SPEED)) return key
This is the main part of the code. We have a while loop where at every iteration we place a new piece in the game.
In Tetris, you can press a certain key to hold a piece. A piece that is held is such a way is available to be used in the future by swapping it with the current piece.
In the code below, we first check if the user wants to swap the current piece with the held piece using the
if __name__ == "__main__": while not quit: # Check if user wants to swap held and current pieces if switch: # swap held_piece and current_piece held_piece, current_piece = current_piece, held_piece switch = False
switch variable is set to false, we assign the
current_piece to the
next_piece and randomly choose a new
else: # Generates the next piece and updates the current piece current_piece = next_piece next_piece = choice(["I", "T", "L", "J", "Z", "S", "O"]) if flag > 0: flag -= 1
Next, we determine the color and position of the
next_piece, and the
# Determines the color and position of the current, next, and held pieces if held_piece == "": held_info = np.array([[0, 0]]), [0, 0, 0] else: held_info = get_info(held_piece) next_info = get_info(next_piece) coords, color = get_info(current_piece) if current_piece == "I": top_left = [-2, 3]
This if statement just checks if the game needs to be terminated (i.e., the tetris pieces have stacked too high), and we do this by checking if the next piece’s spawn location doesn’t overlap with another piece.
if not np.all(board[coords[:,0], coords[:,1]] == 0): break
Next, we add another while loop inside of the main one. Each iteration of this new loop corresponds to the piece moving down by one block.
First, we show the board using our
display() function and receive the keyboard input.
We also make a copy of the original position.
while True: # Shows the board and gets the key press key = display(board, coords, color, next_info, held_info, score, SPEED) # Create a copy of the position dummy = coords.copy()
key variable above stores the ASCII code for the pressed keyboard entry. Depending on which key was pressed, we take different actions.
The a and d keys control the left and right movement of the piece.
if key == ord("a"): # Moves the piece left if it isn't against the left wall if np.min(coords[:,1]) > 0: coords[:,1] -= 1 if current_piece == "I": top_left -= 1 elif key == ord("d"): # Moves the piece right if it isn't against the right wall if np.max(coords[:,1]) < 9: coords[:,1] += 1 if current_piece == "I": top_left += 1
The keys j and l are used to rotate the pieces.
To code rotation, we have three kinds of pieces to deal with – the square piece, the line piece, and all others.
For the square piece, rotating is simple; you don’t do anything!
For anything that’s not a square piece, we can inscribe the piece in a square, which we can rotate.
The line piece is inscribed in a 4×4 square and not a 3×3 square, and therefore we need to treat it differently.
elif key == ord("j") or key == ord("l"): # Rotation mechanism # arr is the array of nearby points which get rotated and pov is the indexes of the blocks within arr if current_piece != "I" and current_piece != "O": if coords[1,1] > 0 and coords[1,1] < 9: arr = coords - 1 + np.array([[[x, y] for y in range(3)] for x in range(3)]) pov = coords - coords + 1 elif current_piece == "I": # The straight piece has a 4x4 array, so it needs seperate code arr = top_left + np.array([[[x, y] for y in range(4)] for x in range(4)]) pov = np.array([np.where(np.logical_and(arr[:,:,0] == pos, arr[:,:,1] == pos)) for pos in coords]) pov = np.array([k for k in np.swapaxes(pov, 1, 2)]) # Rotates the array and repositions the piece to where it is now if current_piece != "O": if key == ord("j"): arr = np.rot90(arr, -1) else: arr = np.rot90(arr) coords = arr[pov[:,0], pov[:,1]]
Lastly, we will handle the w, i, DELETE, and ESC keys.
Pressing w implements a hard drop. Pressing i holds the piece.
The DELETE and ESC keys end the program.
elif key == ord("w"): # Hard drop set to true drop = True elif key == ord("i"): # Goes out of the loop and tells the program to switch held and current pieces if flag == 0: if held_piece == "": held_piece = current_piece else: switch = True flag = 2 break elif key == 8 or key == 27: quit = True break
We next need to check for collisions with other pieces and prevent the piece from moving into or rotating into another piece.
If such a collision occurs, we change the new position back to the original one using our copy of the
coords stored in the
# Checks if the piece is overlapping with other pieces or if it's outside the board, and if so, changes the position to the position before anything happened if np.max(coords[:,0]) < 20 and np.min(coords[:,0]) >= 0: if not (current_piece == "I" and (np.max(coords[:,1]) >= 10 or np.min(coords[:,1]) < 0)): if not np.all(board[coords[:,0], coords[:,1]] == 0): coords = dummy.copy() else: coords = dummy.copy() else: coords = dummy.copy()
Finally, we code the “hard drop.” We use a while loop to check if the piece can move one step down, and stop moving down if it collides with an existing piece or reaches the bottom of the board.
if drop: # Every iteration of the loop moves the piece down by 1 and if the piece is resting on the ground or another piece, then it stops and places it while not place: if np.max(coords[:,0]) != 19: # Checks if the piece is resting on something for pos in coords: if not np.array_equal(board[pos + 1, pos], [0, 0, 0]): place = True break else: # If the position of the piece is at the ground level, then it places place = True if place: break # Keeps going down and checking when the piece needs to be placed coords[:,0] += 1 score += 1 if current_piece == "I": top_left += 1 drop = False
If we don’t hard drop, then we just need to check if the piece needs to be placed (i.e. stop moving). A piece is placed when the piece either reaches the bottom of the board or hits another piece.
If none of the above cases apply, we move the piece down by one.
else: # Checks if the piece needs to be placed if np.max(coords[:,0]) != 19: for pos in coords: if not np.array_equal(board[pos + 1, pos], [0, 0, 0]): place = True break else: place = True if place: # Places the piece where it is on the board for pos in coords: board[tuple(pos)] = color # Resets place to False place = False break # Moves down by 1 coords[:,0] += 1 if key == ord("s"): score += 1 if current_piece == "I": top_left += 1
Finally, for each iteration of the outer while loop, (aka each time a piece is placed,) we check if any lines were scored and we update the points.
# Clears lines and also counts how many lines have been cleared and updates the score lines = 0 for line in range(20): if np.all([np.any(pos != 0) for pos in board[line]]): lines += 1 board[1:line+1] = board[:line] if lines == 1: score += 40 elif lines == 2: score += 100 elif lines == 3: score += 300 elif lines == 4: score += 1200
Install via pip:
$ pip install pytumblr
Install from source:
$ git clone https://github.com/tumblr/pytumblr.git $ cd pytumblr $ python setup.py install
pytumblr.TumblrRestClient is the object you'll make all of your calls to the Tumblr API through. Creating one is this easy:
client = pytumblr.TumblrRestClient( '<consumer_key>', '<consumer_secret>', '<oauth_token>', '<oauth_secret>', ) client.info() # Grabs the current user information
Two easy ways to get your credentials to are:
interactive_console.pytool (if you already have a consumer key & secret)
client.info() # get information about the authenticating user client.dashboard() # get the dashboard for the authenticating user client.likes() # get the likes for the authenticating user client.following() # get the blogs followed by the authenticating user client.follow('codingjester.tumblr.com') # follow a blog client.unfollow('codingjester.tumblr.com') # unfollow a blog client.like(id, reblogkey) # like a post client.unlike(id, reblogkey) # unlike a post
client.blog_info(blogName) # get information about a blog client.posts(blogName, **params) # get posts for a blog client.avatar(blogName) # get the avatar for a blog client.blog_likes(blogName) # get the likes on a blog client.followers(blogName) # get the followers of a blog client.blog_following(blogName) # get the publicly exposed blogs that [blogName] follows client.queue(blogName) # get the queue for a given blog client.submission(blogName) # get the submissions for a given blog
PyTumblr lets you create all of the various types that Tumblr supports. When using these types there are a few defaults that are able to be used with any post type.
The default supported types are described below.
We'll show examples throughout of these default examples while showcasing all the specific post types.
Creating a photo post
Creating a photo post supports a bunch of different options plus the described default options * caption - a string, the user supplied caption * link - a string, the "click-through" url for the photo * source - a string, the url for the photo you want to use (use this or the data parameter) * data - a list or string, a list of filepaths or a single file path for multipart file upload
#Creates a photo post using a source URL client.create_photo(blogName, state="published", tags=["testing", "ok"], source="https://68.media.tumblr.com/b965fbb2e501610a29d80ffb6fb3e1ad/tumblr_n55vdeTse11rn1906o1_500.jpg") #Creates a photo post using a local filepath client.create_photo(blogName, state="queue", tags=["testing", "ok"], tweet="Woah this is an incredible sweet post [URL]", data="/Users/johnb/path/to/my/image.jpg") #Creates a photoset post using several local filepaths client.create_photo(blogName, state="draft", tags=["jb is cool"], format="markdown", data=["/Users/johnb/path/to/my/image.jpg", "/Users/johnb/Pictures/kittens.jpg"], caption="## Mega sweet kittens")
Creating a text post
Creating a text post supports the same options as default and just a two other parameters * title - a string, the optional title for the post. Supports markdown or html * body - a string, the body of the of the post. Supports markdown or html
#Creating a text post client.create_text(blogName, state="published", slug="testing-text-posts", title="Testing", body="testing1 2 3 4")
Creating a quote post
Creating a quote post supports the same options as default and two other parameter * quote - a string, the full text of the qote. Supports markdown or html * source - a string, the cited source. HTML supported
#Creating a quote post client.create_quote(blogName, state="queue", quote="I am the Walrus", source="Ringo")
Creating a link post
#Create a link post client.create_link(blogName, title="I like to search things, you should too.", url="https://duckduckgo.com", description="Search is pretty cool when a duck does it.")
Creating a chat post
Creating a chat post supports the same options as default and two other parameters * title - a string, the title of the chat post * conversation - a string, the text of the conversation/chat, with diablog labels (no html)
#Create a chat post chat = """John: Testing can be fun! Renee: Testing is tedious and so are you. John: Aw. """ client.create_chat(blogName, title="Renee just doesn't understand.", conversation=chat, tags=["renee", "testing"])
Creating an audio post
Creating an audio post allows for all default options and a has 3 other parameters. The only thing to keep in mind while dealing with audio posts is to make sure that you use the external_url parameter or data. You cannot use both at the same time. * caption - a string, the caption for your post * external_url - a string, the url of the site that hosts the audio file * data - a string, the filepath of the audio file you want to upload to Tumblr
#Creating an audio file client.create_audio(blogName, caption="Rock out.", data="/Users/johnb/Music/my/new/sweet/album.mp3") #lets use soundcloud! client.create_audio(blogName, caption="Mega rock out.", external_url="https://soundcloud.com/skrillex/sets/recess")
Creating a video post
Creating a video post allows for all default options and has three other options. Like the other post types, it has some restrictions. You cannot use the embed and data parameters at the same time. * caption - a string, the caption for your post * embed - a string, the HTML embed code for the video * data - a string, the path of the file you want to upload
#Creating an upload from YouTube client.create_video(blogName, caption="Jon Snow. Mega ridiculous sword.", embed="http://www.youtube.com/watch?v=40pUYLacrj4") #Creating a video post from local file client.create_video(blogName, caption="testing", data="/Users/johnb/testing/ok/blah.mov")
Editing a post
Updating a post requires you knowing what type a post you're updating. You'll be able to supply to the post any of the options given above for updates.
client.edit_post(blogName, id=post_id, type="text", title="Updated") client.edit_post(blogName, id=post_id, type="photo", data="/Users/johnb/mega/awesome.jpg")
Reblogging a Post
Reblogging a post just requires knowing the post id and the reblog key, which is supplied in the JSON of any post object.
client.reblog(blogName, id=125356, reblog_key="reblog_key")
Deleting a post
Deleting just requires that you own the post and have the post id
client.delete_post(blogName, 123456) # Deletes your post :(
A note on tags: When passing tags, as params, please pass them as a list (not a comma-separated string):
client.create_text(blogName, tags=['hello', 'world'], ...)
Getting notes for a post
In order to get the notes for a post, you need to have the post id and the blog that it is on.
data = client.notes(blogName, id='123456')
The results include a timestamp you can use to make future calls.
data = client.notes(blogName, id='123456', before_timestamp=data["_links"]["next"]["query_params"]["before_timestamp"])
# get posts with a given tag client.tagged(tag, **params)
This client comes with a nice interactive console to run you through the OAuth process, grab your tokens (and store them for future use).
pyyaml installed to run it, but then it's just:
$ python interactive-console.py
and away you go! Tokens are stored in
~/.tumblr and are also shared by other Tumblr API clients like the Ruby client.
The tests (and coverage reports) are run with nose, like this:
python setup.py test
Learn Free how to create a virtual pen and eraser with python and OpenCV with source code and complete guide. This entire application is built fundamentally on contour detection. It can be thought of as something like closed color curves on compromises that have the same color or intensity, it’s like a blob. In this project we use color masking to get the binary mask of our target color pen, then we use the counter detection to find the location of this pen and the contour to find it.
#python #create virtual pen and eraser with opencv #create virtual pen and eraser with python opencv #programming #opencv #python opencv
Welcome to my Blog, In this article, we will learn python lambda function, Map function, and filter function.
Lambda function in python: Lambda is a one line anonymous function and lambda takes any number of arguments but can only have one expression and python lambda syntax is
Syntax: x = lambda arguments : expression
Now i will show you some python lambda function examples:
#python #anonymous function python #filter function in python #lambda #lambda python 3 #map python #python filter #python filter lambda #python lambda #python lambda examples #python map
No programming language is pretty much as diverse as Python. It enables building cutting edge applications effortlessly. Developers are as yet investigating the full capability of end-to-end Python development services in various areas.
By areas, we mean FinTech, HealthTech, InsureTech, Cybersecurity, and that's just the beginning. These are New Economy areas, and Python has the ability to serve every one of them. The vast majority of them require massive computational abilities. Python's code is dynamic and powerful - equipped for taking care of the heavy traffic and substantial algorithmic capacities.
Programming advancement is multidimensional today. Endeavor programming requires an intelligent application with AI and ML capacities. Shopper based applications require information examination to convey a superior client experience. Netflix, Trello, and Amazon are genuine instances of such applications. Python assists with building them effortlessly.
Python can do such numerous things that developers can't discover enough reasons to admire it. Python application development isn't restricted to web and enterprise applications. It is exceptionally adaptable and superb for a wide range of uses.
Python is known for its tools and frameworks. There's a structure for everything. Django is helpful for building web applications, venture applications, logical applications, and mathematical processing. Flask is another web improvement framework with no conditions.
Web2Py, CherryPy, and Falcon offer incredible capabilities to customize Python development services. A large portion of them are open-source frameworks that allow quick turn of events.
Simple to read and compose
Python has an improved sentence structure - one that is like the English language. New engineers for Python can undoubtedly understand where they stand in the development process. The simplicity of composing allows quick application building.
The motivation behind building Python, as said by its maker Guido Van Rossum, was to empower even beginner engineers to comprehend the programming language. The simple coding likewise permits developers to roll out speedy improvements without getting confused by pointless subtleties.
Utilized by the best
Alright - Python isn't simply one more programming language. It should have something, which is the reason the business giants use it. Furthermore, that too for different purposes. Developers at Google use Python to assemble framework organization systems, parallel information pusher, code audit, testing and QA, and substantially more. Netflix utilizes Python web development services for its recommendation algorithm and media player.
Massive community support
Python has a steadily developing community that offers enormous help. From amateurs to specialists, there's everybody. There are a lot of instructional exercises, documentation, and guides accessible for Python web development solutions.
Today, numerous universities start with Python, adding to the quantity of individuals in the community. Frequently, Python designers team up on various tasks and help each other with algorithmic, utilitarian, and application critical thinking.
Python is the greatest supporter of data science, Machine Learning, and Artificial Intelligence at any enterprise software development company. Its utilization cases in cutting edge applications are the most compelling motivation for its prosperity. Python is the second most well known tool after R for data analytics.
The simplicity of getting sorted out, overseeing, and visualizing information through unique libraries makes it ideal for data based applications. TensorFlow for neural networks and OpenCV for computer vision are two of Python's most well known use cases for Machine learning applications.
Thinking about the advances in programming and innovation, Python is a YES for an assorted scope of utilizations. Game development, web application development services, GUI advancement, ML and AI improvement, Enterprise and customer applications - every one of them uses Python to its full potential.
The disadvantages of Python web improvement arrangements are regularly disregarded by developers and organizations because of the advantages it gives. They focus on quality over speed and performance over blunders. That is the reason it's a good idea to utilize Python for building the applications of the future.
#python development services #python development company #python app development #python development #python in web development #python software development
In this article, I am going to show you,_ how to Create a Video Chat App Using Python OpenCV and Socket Programming__ with__ an easy step-by-step tutorial._
**∘ **Video-Server.py file
**∘ **Video-Client.py file
**· **Github Project Link
#opencv #networking #python #python and opencv #how to create a video chat app #video chat app python