Last active
April 11, 2025 07:29
-
-
Save pepinisillo/3792796623ede0318a7b02023e368ece to your computer and use it in GitHub Desktop.
Programa 40 Juego de piedra, papel o tijeras con la computadora mostrando resultado del juego en terminal Código Assembly ARM64 para RaspbianOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| ______ ____ ____ __ __ | |
| /\ _ \/\ _`\ /'\_/`\ /'___\/\ \\ \ | |
| \ \ \L\ \ \ \L\ \/\ \/\ \__/\ \ \\ \ | |
| \ \ __ \ \ , /\ \ \__\ \ \ _``\ \ \\ \_ | |
| \ \ \/\ \ \ \\ \\ \ \_/\ \ \ \L\ \ \__ ,__\ | |
| \ \_\ \_\ \_\ \_\ \_\\ \_\ \____/\/_/\_\_/ | |
| \/_/\/_/\/_/\/ /\/_/ \/_/\/___/ \/_/ | |
| ♡ ∩_∩ | |
| („• ֊ •„)♡ | |
| | ̄U U ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| | |
| | • Lenguajes de Interfaz en TECNM Campus ITT | | |
| | • Autor: Alejandro Suarez Sandoval | | |
| | • Fecha: 2025/04/10 | | |
| | • Descripción: Programa Juego de piedra, papel o tijeras contra la | | |
| | computadora en Rust y Assembly ARM64 para RaspbianOS. | | |
| | • Demostración: | | |
| | https://asciinema.org/a/714719 | | |
| | • Compilación (Raspberry Pi ARM64): | | |
| | as jankenpon.s -o jankenpon.o | | |
| | ld jankenpon.o -o jankenpon | | |
| | • Ejecución: ./jankenpon | | |
|  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ | |
| ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆ | |
| ═════════•°• Demostración Código en lenguaje Rust •°•═══════ | |
| use std::io::{self, Write}; | |
| use rand::Rng; | |
| #[derive(Debug, Clone, Copy, PartialEq)] | |
| enum Opcion { | |
| Piedra = 1, | |
| Papel = 2, | |
| Tijeras = 3, | |
| } | |
| #[derive(Debug)] | |
| enum Resultado { | |
| Ganas, | |
| Pierdes, | |
| Empate, | |
| } | |
| fn numero_a_opcion(num: u8) -> Option<Opcion> { | |
| match num { | |
| 1 => Some(Opcion::Piedra), | |
| 2 => Some(Opcion::Papel), | |
| 3 => Some(Opcion::Tijeras), | |
| _ => None, | |
| } | |
| } | |
| fn opcion_a_texto(opcion: Opcion) -> &'static str { | |
| match opcion { | |
| Opcion::Piedra => "Piedra", | |
| Opcion::Papel => "Papel", | |
| Opcion::Tijeras => "Tijeras", | |
| } | |
| } | |
| fn determinar_ganador(usuario: Opcion, computadora: Opcion) -> Resultado { | |
| if usuario == computadora { | |
| return Resultado::Empate; | |
| } | |
| match (usuario, computadora) { | |
| (Opcion::Piedra, Opcion::Tijeras) => Resultado::Ganas, | |
| (Opcion::Papel, Opcion::Piedra) => Resultado::Ganas, | |
| (Opcion::Tijeras, Opcion::Papel) => Resultado::Ganas, | |
| _ => Resultado::Pierdes, | |
| } | |
| } | |
| fn obtener_eleccion_usuario() -> Option<Opcion> { | |
| print!("Elige: 1-Piedra, 2-Papel, 3-Tijeras, 0-Salir: "); | |
| io::stdout().flush().unwrap(); | |
| let mut entrada = String::new(); | |
| io::stdin().read_line(&mut entrada).expect("Error al leer la entrada"); | |
| let num = entrada.trim().parse::<u8>().ok()?; | |
| if num == 0 { | |
| return None; | |
| } | |
| numero_a_opcion(num) | |
| } | |
| fn eleccion_computadora() -> Opcion { | |
| let mut rng = rand::thread_rng(); | |
| let num = rng.gen_range(1..=3); | |
| numero_a_opcion(num).unwrap() | |
| } | |
| fn main() { | |
| println!("¡Bienvenido a Piedra, Papel o Tijeras!"); | |
| loop { | |
| let opcion_usuario = match obtener_eleccion_usuario() { | |
| Some(opcion) => opcion, | |
| None => { | |
| println!("¡Gracias por jugar! Adiós."); | |
| break; | |
| } | |
| }; | |
| println!("Tu elección: {}", opcion_a_texto(opcion_usuario)); | |
| let opcion_computadora = eleccion_computadora(); | |
| println!("PC eligió: {}", opcion_a_texto(opcion_computadora)); | |
| match determinar_ganador(opcion_usuario, opcion_computadora) { | |
| Resultado::Ganas => println!("¡Ganaste!"), | |
| Resultado::Pierdes => println!("¡Perdiste!"), | |
| Resultado::Empate => println!("¡Empate!"), | |
| } | |
| println!(); | |
| } | |
| } | |
| ════════════════════•°• ☆ •°•══════════════════════════════ | |
| /* | |
| /* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆ | |
| ═════════════•°• Código en ARM64 Assembly •°•═════════════ */ | |
| // Constantes | |
| .equ SYS_READ, 63 // Syscall para leer | |
| .equ SYS_WRITE, 64 // Syscall para escribir | |
| .equ SYS_EXIT, 93 // Syscall para salir | |
| .equ STDIN, 0 // Descriptor de archivo para entrada estándar | |
| .equ STDOUT, 1 // Descriptor de archivo para salida estándar | |
| .equ STDERR, 2 // Descriptor de archivo para error estándar | |
| .equ PIEDRA, 1 // Valor para piedra | |
| .equ PAPEL, 2 // Valor para papel | |
| .equ TIJERAS, 3 // Valor para tijeras | |
| .equ MAX_RAND, 3 // Valor máximo para generación aleatoria | |
| .section .data | |
| // Constantes para el generador congruencial lineal | |
| lcg_a: | |
| .quad 6364136223846793005 | |
| lcg_c: | |
| .quad 1442695040888963407 | |
| bienvenida: | |
| .ascii "¡Bienvenido al juego de Piedra, Papel o Tijeras!\n\n" | |
| bienvenida_len = . - bienvenida | |
| menu: | |
| .ascii "Escoge una opción:\n" | |
| .ascii "1. Piedra\n" | |
| .ascii "2. Papel\n" | |
| .ascii "3. Tijeras\n" | |
| .ascii "0. Salir\n" | |
| .ascii "Tu elección: " | |
| menu_len = . - menu | |
| eleccion_pc: | |
| .ascii "La computadora eligió: " | |
| eleccion_pc_len = . - eleccion_pc | |
| piedra_str: | |
| .ascii "Piedra\n" | |
| piedra_len = . - piedra_str | |
| papel_str: | |
| .ascii "Papel\n" | |
| papel_len = . - papel_str | |
| tijeras_str: | |
| .ascii "Tijeras\n" | |
| tijeras_len = . - tijeras_str | |
| ganaste: | |
| .ascii "¡Has ganado!\n\n" | |
| ganaste_len = . - ganaste | |
| perdiste: | |
| .ascii "¡Has perdido!\n\n" | |
| perdiste_len = . - perdiste | |
| empate: | |
| .ascii "¡Empate!\n\n" | |
| empate_len = . - empate | |
| opcion_invalida: | |
| .ascii "Opción inválida. Intenta de nuevo.\n\n" | |
| opcion_invalida_len = . - opcion_invalida | |
| adios: | |
| .ascii "¡Gracias por jugar! ¡Hasta pronto!\n" | |
| adios_len = . - adios | |
| .section .bss | |
| .lcomm buffer, 8 // Buffer para la entrada del usuario | |
| .lcomm seed, 8 // Semilla para el generador de números aleatorios | |
| .section .text | |
| .global _start | |
| _start: | |
| // Inicializar la semilla con el tiempo actual (contador de ciclos) | |
| mrs x0, CNTVCT_EL0 // Leer el contador de ciclos virtual | |
| adr x20, seed // Obtener la dirección de seed | |
| str x0, [x20] // Guardar como semilla | |
| // Mostrar mensaje de bienvenida | |
| mov x0, STDOUT | |
| adr x1, bienvenida | |
| mov x2, bienvenida_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| main_loop: | |
| // Mostrar menú | |
| mov x0, STDOUT | |
| adr x1, menu | |
| mov x2, menu_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| // Leer elección del usuario | |
| mov x0, STDIN | |
| adr x1, buffer | |
| mov x2, 8 | |
| mov x8, SYS_READ | |
| svc 0 | |
| // Procesar la elección del usuario | |
| ldrb w19, [x1] // Cargar el primer byte | |
| sub w19, w19, '0' // Convertir ASCII a entero | |
| // Comprobar si el usuario quiere salir | |
| cmp w19, 0 | |
| beq salir | |
| // Comprobar si la elección es válida | |
| cmp w19, 1 | |
| blt opcion_invalida_msg | |
| cmp w19, 3 | |
| bgt opcion_invalida_msg | |
| // La elección es válida, generar la elección de la computadora | |
| bl random | |
| mov w20, w0 // w20 = elección de la computadora (1-3) | |
| // Mostrar la elección de la computadora | |
| mov x0, STDOUT | |
| adr x1, eleccion_pc | |
| mov x2, eleccion_pc_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| // Imprimir la elección de la computadora | |
| cmp w20, PIEDRA | |
| beq imprimir_piedra | |
| cmp w20, PAPEL | |
| beq imprimir_papel | |
| cmp w20, TIJERAS | |
| beq imprimir_tijeras | |
| continuar_despues_imprimir: | |
| // Determinar el resultado | |
| cmp w19, w20 | |
| beq es_empate | |
| // Comprobar si el usuario gana | |
| cmp w19, PIEDRA | |
| beq check_piedra | |
| cmp w19, PAPEL | |
| beq check_papel | |
| cmp w19, TIJERAS | |
| beq check_tijeras | |
| b main_loop | |
| check_piedra: | |
| cmp w20, TIJERAS | |
| beq usuario_gana | |
| b usuario_pierde | |
| check_papel: | |
| cmp w20, PIEDRA | |
| beq usuario_gana | |
| b usuario_pierde | |
| check_tijeras: | |
| cmp w20, PAPEL | |
| beq usuario_gana | |
| b usuario_pierde | |
| imprimir_piedra: | |
| mov x0, STDOUT | |
| adr x1, piedra_str | |
| mov x2, piedra_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b continuar_despues_imprimir | |
| imprimir_papel: | |
| mov x0, STDOUT | |
| adr x1, papel_str | |
| mov x2, papel_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b continuar_despues_imprimir | |
| imprimir_tijeras: | |
| mov x0, STDOUT | |
| adr x1, tijeras_str | |
| mov x2, tijeras_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b continuar_despues_imprimir | |
| es_empate: | |
| mov x0, STDOUT | |
| adr x1, empate | |
| mov x2, empate_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b main_loop | |
| usuario_gana: | |
| mov x0, STDOUT | |
| adr x1, ganaste | |
| mov x2, ganaste_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b main_loop | |
| usuario_pierde: | |
| mov x0, STDOUT | |
| adr x1, perdiste | |
| mov x2, perdiste_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b main_loop | |
| opcion_invalida_msg: | |
| mov x0, STDOUT | |
| adr x1, opcion_invalida | |
| mov x2, opcion_invalida_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| b main_loop | |
| salir: | |
| // Mostrar mensaje de despedida | |
| mov x0, STDOUT | |
| adr x1, adios | |
| mov x2, adios_len | |
| mov x8, SYS_WRITE | |
| svc 0 | |
| // Salir del programa | |
| mov x0, 0 | |
| mov x8, SYS_EXIT | |
| svc 0 | |
| // Función para generar un número aleatorio entre 1 y 3 | |
| random: | |
| // Cargar la semilla actual | |
| adr x3, seed | |
| ldr x0, [x3] | |
| // Cargar las constantes desde la sección de datos | |
| adr x1, lcg_a | |
| ldr x1, [x1] | |
| adr x2, lcg_c | |
| ldr x2, [x2] | |
| // Realizar la operación del LCG: x_next = (a * x + c) mod 2^64 | |
| mul x0, x0, x1 | |
| add x0, x0, x2 | |
| str x0, [x3] // Guardar la nueva semilla | |
| // Reducir al rango [1,3] | |
| lsr x0, x0, 32 // Usar los bits superiores que tienen mejor distribución | |
| mov x1, MAX_RAND | |
| udiv x2, x0, x1 | |
| msub x0, x2, x1, x0 // x0 = x0 % MAX_RAND (0-2) | |
| add w0, w0, 1 // Convertir a rango 1-3 | |
| ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment