Ping-Pong rust: a project for your first dev-job
Tags: rust, programming, beginners, tutorial
Published: 2023-11-15 11:31:16

If you're looking for your first job as a Rust developer and are considering a project for your professional portfolio, this option could be a great proposal.

Let's add the [ping-pong](https://github.com/EduLMoraes/ping-pong) repository created by Eduardo Moraes and analyze the code:

`git clone https://github.com/EduLMoraes/ping-pong.git`

`cargo run --release`

Project structure:

![structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oqyaac8i6vkly2p2imf.png)

## main.rs

```rust
mod prelude;
use crate::prelude::*;

fn main() {
    loop{
        let choice: String = menu();

        if choice == "A".to_string() || choice == "a".to_string(){
            let lines: i32 = 20; //var("LINES").expect("Erro ao coletar 'LINES'").trim().parse::<i32>().expect("Erro ao converter 'COLUMNS' pra inteiro");
            let columns: i32 = 70; //var("COLUMNS").expect("Erro ao coletar 'COLUMNS'").trim().parse::<i32>().expect("Erro ao converter 'COLUMNS' pra inteiro");
            let board: Vec<Vec<char>> = vec![vec![' '; columns as usize]; lines as usize];
            let player: Player = Player::new();
            let scoreboard: Scoreboard = Scoreboard::new();
            let ball: Ball = Ball::new(lines, columns);
            let mut machine: Player = Player::new();
            
            machine.x = columns-2;

            let is_player_win: bool = play(player, machine, ball, scoreboard, board);
            if is_player_win {
                winner();
            }
            else{
                loser();
            }
        }
        else if choice == "B".to_string() || choice == "b".to_string(){
            instruct();
        }
        else{
            break;
        }
    }
}
```

The code defines a main function where the program runs in an infinite loop. Inside the loop, it presents a menu to the user by calling the menu function. Based on the user's choice (A, B, or anything else), it takes different actions.

If the user chooses option A (or a), the program initializes variables for lines and columns, creates a game board represented by a vector of vectors of characters, and sets up instances of player, scoreboard, and ball. It also initializes a machine player. The game then proceeds by calling the play function, and based on the outcome, either the winner or loser function is called.

If the user chooses option B (or b), the instruct function is called.

If the user chooses any other option, the program breaks out of the loop, effectively ending the program.

## position.rs

```rust
use crate::structs::{Player, Ball};

pub fn position_player(mut player: Player, mut board: Vec<Vec<char>>) -> (Player, Vec<Vec<char>>){
    if board.len() <= 0 {
        return (player, board);
    }

    let columns = board[0].len() as i32;
    let lines = board.len() as i32;

    player.x = player.x.max(0);
    player.y = player.y.max(0);

    if player.width == 1 && player.height == 1 {
        board[player.y as usize][player.x as usize] = '|';
    }
    else{
        let tmp_x = player.x;
        let tmp_y = player.y;

        for _i in 1..=player.width{
    
            if player.x >= columns || player.x >= player.width{
                player.x -= 1;
            }

            let y_init = player.y;
    
            for y in 0..lines{
                if y == player.y{
                    if y < player.height{
                        board[player.y as usize][player.x as usize] = '|';
                        player.y += 1;
                    } 
                }
    
                for x in 0..columns{
                    if x == player.x && y == player.y{
                        if y < player.height && x < player.width{
                            board[y as usize][player.x as usize] = '|';
                        }
                    }
                }
            }
    
            player.x += 1;
            if player.y >= lines || player.y >= player.height{
                player.y -= player.height;
            }
            if player.y != y_init{
                player.y = y_init;
            }
        
        }
        player.y = tmp_y;
        player.x = tmp_x;
    }

    (player, board)
}

pub fn move_ball(mut ball: Ball, mut board: Vec<Vec<char>>) -> (Ball, Vec<Vec<char>>){
    if board.len() <= 0 {
        return (ball, board);
    }

    ball.x = ball.x.max(0);
    ball.y = ball.y.max(0);

    board[ball.y as usize][ball.x as usize] = '@';

    (ball, board)
}
```

### `position_player` function:

1. The function checks if the board has a length less than or equal to 0, and if so, it returns the original player and board.
2. It calculates the number of columns and lines in the board.
3. Adjusts the player's coordinates to ensure they are not negative.
4. Depending on the player's dimensions (width and height), it updates the board to represent the player's position using the character '|'.
5. The function handles cases where the player has a width or height greater than 1, adjusting the player's position on the board accordingly.

### `move_ball` function:

1. Similar to position_player, it checks if the board has a length less than or equal to 0 and returns the original ball and board if true.
2. Adjusts the ball's coordinates to ensure they are not negative.
3. Updates the board to represent the ball's position using the character '@'.

## It's your time

In the competitive landscape of the tech industry, a well-crafted professional portfolio serves as a powerful asset for individuals seeking employment in the field of software development. In this case make your own ping-pong system is a greater challenge for new developers!