Sprawdź się
W wybranym przez siebie języku programowania napisz program wielowątkowy, który po uruchomieniu wyświetli planszę co najmniej 10 na 10, na której będą poruszały się co najmniej dwa niezależne obiekty. Powinny być one niezależnymi od siebie wątkami. W sytuacji, gdy obydwa obiekty znajdą się na jednym polu, ma się wyświetlić tylko jeden z nich, natomiast drugi w takiej sytuacji powinien się wyświetlić po przesunięciu na wolne pole.
Przykładowe rozwiązanie w języku C++:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
class Obiekt {
public:
int x;
int y;
static enum Kierunek { polnoc = 0, wschod = 1, poludnie = 2, zachod = 3 };
Kierunek kierunekRuchu;
Obiekt(int x, int y, Kierunek kierunek)
{
this->x = x;
this->y = y;
this->kierunekRuchu = kierunekRuchu;
}
Obiekt(int x, int y)
{
this->x = x;
this->y = y;
kierunekRuchu = polnoc;
}
void porusz()
{
while(true)
{
this_thread::sleep_for(std::chrono::milliseconds(2000));
if (kierunekRuchu == polnoc)
y++;
else if (kierunekRuchu == poludnie)
y--;
else if (kierunekRuchu == wschod)
x++;
else
x--;
}
}
int zwrocX()
{
return x;
}
int zwrocY()
{
return y;
}
};
class Plansza {
public:
vector<Obiekt*> obiekty;
int rozmiarPlanszy = 10;
void wyswietl()
{
while (true)
{
this_thread::sleep_for(std::chrono::milliseconds(1000));
for (int i = rozmiarPlanszy; i >= 0; i--)
{
for (int j = 0; j <= rozmiarPlanszy; j++)
{
bool poleZajete = false;
for (int m = 0; m < obiekty.size(); m++)
{
if (obiekty[m]->zwrocX() == i && obiekty[m]->zwrocY() == j)
poleZajete = true;
}
if (poleZajete)
cout << "o ";
else
cout << "+ ";
}
cout << "\n";
}
cout << "\n";
}
}
void dodajObiektDoListy(Obiekt* obiektDoDodania)
{
obiekty.push_back(obiektDoDodania);
}
};
int main(int argc, char* argv[])
{
Plansza plansza;
Obiekt obiektTestowy1 = Obiekt(0, 0);
Obiekt obiektTestowy2 = Obiekt(4, 4, obiektTestowy1.poludnie);
Obiekt obiektTestowy3 = Obiekt(7, 2, obiektTestowy1.wschod);
plansza.dodajObiektDoListy(&obiektTestowy1);
plansza.dodajObiektDoListy(&obiektTestowy2);
plansza.dodajObiektDoListy(&obiektTestowy3);
thread watekPlanszy(&Plansza::wyswietl, &plansza);
thread watekTestowy1(&Obiekt::porusz, &obiektTestowy1);
thread watekTestowy2(&Obiekt::porusz, &obiektTestowy2);
thread watekTestowy3(&Obiekt::porusz, &obiektTestowy3);
watekPlanszy.join();
watekTestowy1.join();
watekTestowy2.join();
watekTestowy3.join();
return 0;
}
Przykładowe rozwiązanie w języku Java:
public class Main {
public static void main(String[] args) {
Plansza plansza = new Plansza();
Thread watekPlanszy = new Thread(plansza);
Obiekt obiekt1 = new Obiekt(0,0, Obiekt.Kierunek.polnoc);
Obiekt obiekt2 = new Obiekt(4,1, Obiekt.Kierunek.wschod);
Obiekt obiekt3= new Obiekt(6,2, Obiekt.Kierunek.zachod);
plansza.dodajObiektDoListy(obiekt1);
plansza.dodajObiektDoListy(obiekt2);
plansza.dodajObiektDoListy(obiekt3);
Thread watekObiektu1 = new Thread(obiekt1);
Thread watekObiektu2 = new Thread(obiekt2);
Thread watekObiektu3 = new Thread(obiekt3);
watekObiektu1.start();
watekObiektu2.start();
watekObiektu3.start();
watekPlanszy.start();
}
}
import static java.lang.Thread.sleep;
public class Obiekt implements Runnable{
public int x;
public int y;
@Override
public void run() {
porusz();
}
static enum Kierunek{
polnoc, wschod, poludnie, zachod;
}
Kierunek kierunekRuchu;
Obiekt(int x, int y, Kierunek kierunekRuchu) {
this.x = x;
this.y = y;
this.kierunekRuchu = kierunekRuchu;
}
Obiekt(int x, int y) {
this.x = x;
this.y = y;
kierunekRuchu = Kierunek.polnoc;
}
void porusz() {
while(true){
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(kierunekRuchu == Kierunek.polnoc)
y++;
else if(kierunekRuchu == Kierunek.poludnie)
y--;
else if(kierunekRuchu == Kierunek.wschod)
x++;
else if(kierunekRuchu == Kierunek.zachod)
x--;
}
}
int zwrocX(){
return x;
}
int zwrocY(){
return y;
}
}
import javax.swing.*;
import java.util.ArrayList;
import static java.lang.Thread.sleep;
public class Plansza implements Runnable{
ArrayList<Obiekt> obiekty = new ArrayList();
int rozmiarPlanszy = 10;
private JFrame okienkoGraficzne = new JFrame();
private JTextArea grafikaTekstowa = new JTextArea();
void wyswietl() {
while(true){
grafikaTekstowa.setText("");
for(int i = rozmiarPlanszy-1; i>= 0; i--){
for(int j = 0; j<rozmiarPlanszy; j++){
int poleZajete = 0;
for(int m = 0; m<obiekty.size(); m++){
if(obiekty.get(m).x == i && obiekty.get(m).y == j)
poleZajete++;
}
if(poleZajete > 0)
grafikaTekstowa.append("o ");
else
grafikaTekstowa.append("+ ");
}
grafikaTekstowa.append("\n ");
}
grafikaTekstowa.append("\n ");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void dodajObiektDoListy(Obiekt obiektDoDodania){
obiekty.add(obiektDoDodania);
}
Plansza()
{
grafikaTekstowa.setSize(500, 500);
grafikaTekstowa.setEditable(false);
okienkoGraficzne.setSize(500, 500);
okienkoGraficzne.setVisible(true);
okienkoGraficzne.add(grafikaTekstowa);
}
@Override
public void run() {
wyswietl();
}
}
Przykładowe rozwiązanie w języku Python:
import threading
import time
class Obiekt:
x = 0
y = 0
from enum import Enum
Kierunek = Enum('Kierunek','polnoc poludnie wschod zachod')
kierunekRuchu = Kierunek.polnoc
def __init__(self, x, y, kierunekRuchu):
self.x = x
self.y = y
self.kierunekRuchu = kierunekRuchu
def porusz(self):
while 1:
time.sleep(4)
if self.kierunekRuchu == self.Kierunek.polnoc:
self.y = self.y + 1
elif self.kierunekRuchu == self.Kierunek.poludnie:
self.y = self.y - 1
elif self.kierunekRuchu == self.Kierunek.wschod:
self.x = self.x + 1
elif self.kierunekRuchu == self.Kierunek.zachod:
self.x = self.x - 1
class Plansza:
rozmiarPlanszy = 10
obiekty = []
def wyswietl(self):
while 1:
time.sleep(2)
i = self.rozmiarPlanszy
while i >= 0:
j = 0
while j <= self.rozmiarPlanszy:
poleZajete = 0
for m in self.obiekty:
if m.x == i and m.y == j:
poleZajete = poleZajete + 1
if poleZajete > 0:
print("o", end=' ')
else:
print("+", end=' ')
j = j + 1
print("", end='\n')
i = i - 1
print("", end='\n')
obiekt1 = Obiekt(0, 2, Obiekt.Kierunek.polnoc)
obiekt2 = Obiekt(6, 6, Obiekt.Kierunek.poludnie)
obiekt3 = Obiekt(0, 5, Obiekt.Kierunek.wschod)
watekObiektu1 = threading.Thread(target=Obiekt.porusz, args=(obiekt1, ))
watekObiektu2 = threading.Thread(target=Obiekt.porusz, args=(obiekt2, ))
watekObiektu3 = threading.Thread(target=Obiekt.porusz, args=(obiekt3, ))
plansza = Plansza()
plansza.obiekty.append(obiekt1)
plansza.obiekty.append(obiekt2)
plansza.obiekty.append(obiekt3)
watekPlanszy = threading.Thread(target=Plansza.wyswietl, args=(plansza, ))
watekPlanszy.start()
watekObiektu1.start()
watekObiektu2.start()
watekObiektu3.start()
watekPlanszy.join()
Zmodyfikuj program tak, aby w sytuacji, gdy obiekt wyjdzie poza granice planszy, pojawiał się z jej drugiej strony.
Zaimplementuj synchronizację wątków tak, aby plansza wyświetlała się dopiero wtedy, gdy poruszą się wszystkie obiekty.