๋‚ด ์ธ์ƒ์—์„œ ๋ฏฟ์„ ๊ฑด ์˜ค์ง ๋‚˜ ์ž์‹ ๋ฟ!

The only one you can truly trust is yourself.

๊ฒŒ์ž„์‚ฐ์—… ์ด์•ผ๊ธฐ/๊ฒŒ์ž„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋งค์น˜๋ฉ”์ดํ‚น ์„œ๋ฒ„ ๊ฐœ๋ฐœ...

๐ŸŽฎinspirer9 2023. 2. 24. 10:38
728x90
๋ฐ˜์‘ํ˜•

https://career.programmers.co.kr/job_positions/9328?personalized=true&referer=open_challenge 

 

์ฑ„์šฉ ๊ณต๊ณ 

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

career.programmers.co.kr

์„œ๋ฒ„ ๊ฐœ๋ฐœ, ๋งค์น˜๋ฉ”์ดํ‚น, MMR, MMORPG๋‚˜ FPS๊ฐ™์€ ์˜จ๋ผ์ธ ๊ฒŒ์ž„์„ ์ข‹์•„ํ•˜๋Š” ์„ฑํ–ฅ์œผ๋กœ ์ธํ•ด ๊ณต๋ถ€์˜ ๋ฐฉํ–ฅ์ด ํ•ญ์ƒ ์„œ๋ฒ„ ์ชฝ์„ ํ–ฅํ•œ๋‹ค. ์˜ค๋Š˜ ์šฐ์—ฐํžˆ ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์— ์˜ฌ๋ผ์˜จ ์ฑ„์šฉ ๊ณต๊ณ ๋ฅผ ๋ณด๊ณ , ๋‚ด๊ฐ€ ์—”์ง€๋‹ˆ์–ด์˜€์œผ๋ฉด ์ด๋Ÿฐ๊ฑฐ ๋”ฑ ์ข‹์•„ํ–ˆ์„ ๊ฒƒ ๊ฐ™์€ ํฌ์ง€์…˜์ด ์žˆ์–ด์„œ ์—ด์–ด ์‚ดํŽด๋ณด์•˜๋‹ค.

๊ธฐ์ˆ  ์Šคํƒ์—์„œ MySQL๊ณผ Python, Go๋ฅผ ์ œ์™ธํ•˜๋ฉด ์ž˜ ๋ชจ๋ฅด๋Š” ๊ฒƒ... ์ด๋Ÿฐ ๊ฑด ์ฝ์–ด๋‘๊ณ  ์ด๋ฆ„๋งŒ ๊ธฐ์–ตํ•ด๋„ ๋„์›€์ด ๋˜๊ฒ ์ง€?ํ•˜๋ฉด์„œ ๋ณด๊ณ  ์žˆ๋Š”๋ฐ ์—…๋ฌด ์†Œ๊ฐœ์— ์œ ์‚ฌํ•œ ์„œ๋น„์Šค์™€ ์˜คํ”ˆ์†Œ์ˆ˜ ๋„๊ตฌ๋ฅผ ์•Œ๋ ค์ค€๋‹ค.

์ด๋Ÿฐ ์˜คํ”ˆ ์†Œ์Šค๊ฐ€ ์žˆ๋Š” ์ค„๋„ ๋ชฐ๋ž๋„ค?

๋งค์น˜๋ฉ”์ดํ‚น ์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—…๋ฌด๋ฅผ ๋งก๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„์œผ๋กœ ์œ ์ž…๋˜๋Š” ์š”์ฒญ ๋Œ€๊ธฐ์—ด์—์„œ ์ œํ•œ๋œ ์‹œ๊ฐ„ ๋‚ด์— ์ตœ์ ์˜ ์กฐํ•ฉ์„ ์ฐพ์•„์ฃผ๋Š” ๋งค์น˜๋ฉ”์ดํ‚น ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

์œ ์‚ฌํ•œ ์„œ๋น„์Šค ๋˜๋Š” ์˜คํ”ˆ์†Œ์Šค ๋„๊ตฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜คํ”ˆ ๋งค์น˜

Open Match

 
 
Open Match is a flexible match making system built to scale with your game. Flexible. Write code, not config, to determine how matches should be made.



ํŠœํ† ๋ฆฌ์–ผ์ด... ์ด๊ฒŒ ๋ฌด์Šจ ์–ธ์–ด์ธ๊ฐ€?


๋‚ด๊ฐ€ ์•Œ๊ณ  ์‹ถ์—ˆ๋˜ ๋ถ€๋ถ„์€... Build a Custom Evaluator

https://open-match.dev/site/docs/tutorials/customevaluator/
๋งค์น˜ ๋๋‚˜๋ฉด ์—ฌ๊ธฐ์„œ ๊ณ„์‚ฐํ•˜๋Š”๊ฐ€ ๋ณด๋‹ค.

func evaluate(proposals []*pb.Match) ([]string, error) {
  // Core evaluation logic
  return []string{}, nil
}

ํ•˜๋Š” ์ผ

๋งค์น˜๋ฉ”์ดํ‚น ์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž

๋„ฅ์Šจ ๊ฒŒ์ž„์„ ์ฆ๊ธฐ๋Š” ์ˆ˜๋งŽ์€ ์œ ์ €๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ๊ธ์ •์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์„ ์ด๋Œ์–ด๋‚ด๊ณ  ์œ ์ €์—๊ฒŒ ๋” ๋งŽ์€ ์žฌ๋ฏธ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด ๋งค์น˜๋ฉ”์ด์ปค๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฒŒ์ž„์˜ ๋Œ€๊ฒฐ ์ƒ๋Œ€๋ฅผ ์ฐพ์•„์ฃผ๋Š” ๋ฒ”์šฉ ๋งค์น˜๋ฉ”์ดํ‚น ์‹œ์Šคํ…œ์„ ์‹œ์ž‘์œผ๋กœ ์†”๋ฃจ์…˜ ์ ์šฉ ๊ฒŒ์ž„์„ ๋Š˜๋ ค๊ฐ€๊ณ  ์žˆ์œผ๋ฉฐ, ๊ธธ๋“œ์™€ ์นœ๊ตฌ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ์„ฑํ™”๋ฅผ ์œ„ํ•œ ์„œ๋น„์Šค๋กœ ์ฃผ์ œ ํ™•์žฅ์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋„ฅ์Šจ์˜ ๋‹ค์–‘ํ•œ ๊ฒŒ์ž„์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฒ”์šฉ์  ์‹œ์Šคํ…œ์„ ์ฐฝ์กฐํ•˜๋Š” ์ผ์€, ๋ถ„๋ช… ๋‹จ์ผ ๊ฒŒ์ž„์„ ๋งŒ๋“ค๊ณ  ๋ผ์ด๋ธŒํ•˜๋Š” ๊ฒƒ ์ด์ƒ์˜ ๋„์ „์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์˜ ๋ชฐ์ž…๋„๋ฅผ ๋†’์ด๋Š” ๋งค์น˜๋ฉ”์ดํ‚น ๊ทœ์น™์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

ํŒ€ ๋‚ด์˜ ๋ฐ์ดํ„ฐ ๊ณผํ•™์ž, ๋จธ์‹ ๋Ÿฌ๋‹ ์—”์ง€๋‹ˆ์–ด์˜ ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋ฅผ ์ œํ’ˆํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ํ”Œ๋ ˆ์ด์–ด์˜ ์ •ํ™•ํ•œ ์‹ค๋ ฅ์„ ์ถ”์ •ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ํ”Œ๋ ˆ์ด์–ด์˜ ๋ชฐ์ž…์„ ๊ณ ๋ คํ•œ ๋งค์นญ ํ’ˆ์งˆ ํ‰๊ฐ€ ๋ฐฉ๋ฒ•
๋งค์น˜๋ฉ”์ดํ‚น ๊ทœ์น™์„ ๋Œ€์ƒ ๊ฒŒ์ž„์— ์ตœ์ ํ™”ํ•˜์—ฌ ๋งž์ถค ๊ตฌํ˜„ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฒŒ์ž„์—๋„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์ผ๋ฐ˜ํ™”ํ•˜๋Š” ๊ฐœ๋ฐœ์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
์ž๊ฒฉ ์กฐ๊ฑด
ํ•œ ๊ฐ€์ง€ ์ด์ƒ์˜ ๊ฐœ๋ฐœ ์–ธ์–ด(Python, C++, C#, Rust, Go ๋“ฑ)์— ์ˆ™๋ จ๋œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋Šฅ๋ ฅ
๊ธฐ์ˆ  ์Šคํƒ์€ ํ•ฉ๋ฅ˜ ์ดํ›„์— ์ ์‘ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
์šฐ๋Œ€์‚ฌํ•ญ
• ๊ฒŒ์ž„ ๊ฐœ๋ฐœ ๋˜๋Š” ๋ผ์ด๋ธŒ ์„œ๋น„์Šค ๊ฒฝํ—˜์ด ์žˆ์œผ์‹  ๋ถ„
• ๊ฒŒ์ž„์„œ๋ฒ„ ๋˜๋Š” ๊ทธ์™€ ์œ ์‚ฌํ•œ ๋ถ„์‚ฐ ์‹ค์‹œ๊ฐ„ ์‹œ์Šคํ…œ์˜ ์ƒํƒœ ๋™๊ธฐํ™” ๋ฐ ์žฅ์•  ํ—ˆ์šฉ ์„ค๊ณ„ ๊ฒฝํ—˜

๊ฐœ๋ฐœํ™˜๊ฒฝ

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” 2018๋…„ ์ดํ›„๋กœ ๋ผ์ด๋ธŒ๊ฒŒ์ž„์— ์ œ๊ณต ์ค‘์ด๋ฉฐ ๋‹ค์Œ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฆฌ๋ทฐ

GitLab ์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋ฆฌ๋ทฐ, ์ผ๊ฐ ๊ด€๋ฆฌ, CI/CD ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ๊ฒฐํ•จ์„ ์ฐพ๋Š” ์ ˆ์ฐจ๊ฐ€ ์•„๋‹ˆ๋ผ ๋น„๋™๊ธฐ๋กœ ํ•จ๊ป˜ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.์ฝ”๋“œ๋ฆฌ๋ทฐ๊ฐ€ ๋จธ์ง€/๋ฆด๋ฆฌ์ฆˆ ์Šน์ธ ์ ˆ์ฐจ๋ผ๊ธฐ๋ณด๋‹ค ๋น„๋™๊ธฐ ์˜จ๋ผ์ธ ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.
  • ์™„์„ฑ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์ผ๋ฐฉ์ ์œผ๋กœ ๊ณต์œ ํ•˜์ง€ ์•Š๊ณ , ์ž‘์—… ๊ณผ์ •์— ์ตœ๋Œ€ํ•œ ์˜๊ฒฌ์„ ๋‚˜๋ˆ„๊ณ  ๊ทธ๋Ÿฌํ•œ ์˜์‚ฌ ๊ฒฐ์ •์˜ ๊ณผ์ •์„ ๊ทธ๋Œ€๋กœ ๊ธฐ๋ก, ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ์ฃผ์ œ๋กœ ํ•จ๊ป˜ ๊ณ ๋ฏผํ•˜๊ณ  ๊ณต๊ฐํ•ด์ฃผ๋Š” ๋™๋ฃŒ๊ฐ€ ์žˆ์œผ๋ฉด ๊ณ ๋ฆฝ๊ฐ์ด ์ค„์–ด๋“ค๊ณ  ๋” ๋‚˜์€ ๊ฒฐ์ •์„ ๋‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜์‚ฌ ๊ฒฐ์ • ๊ณผ์ •์„ ๊ธฐ๋กํ•จ์œผ๋กœ์จ "๊ณผ๊ฑฐ์— ๋‚ด๋ฆฐ ๊ฒฐ์ •์ด ์ด์œ ๊ฐ€ ํ˜„์žฌ๋„ ์œ ํšจํ•œ์ง€" ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ๋ฐœ ํŒ€ & ํ™˜๊ฒฝ
  • AWS Step Functions, Apache Airflow, Amazon Web Services(AWS), Amazon Kinesis, JavaScript, Vue.js, Docker, Nginx, Django, Kibana, AWS S3, Apache Hive, AWS Glue, Apache Spark, AWS EMR, PySpark, PyTorch, Kubernetes, AWS EKS, Tensorflow, AWS SageMaker, GitLab, AWS Kinesis, AWS Lambda, AWS Elasticsearch Service, AWS CloudWatch, MySQL, AWS RDS, Redis, AWS ElastiCache, AWS ECS, Python, Go

์˜คํ”ˆ ๋งค์น˜๋ผ๋Š” ์ข‹์€ ๊ฑธ ์•Œ์•˜๋‹ค. ์‹œ๊ฐ„ ๋‚˜๋ฉด ์‚ดํŽด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

https://github.com/googleforgames/open-match/blob/main/tutorials/custom_evaluator/solution/evaluator/evaluate/evaluator.go

Building the Evaluator

Please revisit the Evaluator overview section in the default Evaluator tutorial as it specifically calls out the scenario in which a custom Evaluator is needed.
This tutorial provides an Evaluator scaffold ($TUTORIALROOT/evaluator) as a starting point. The basis Evaluator server implementation in $TUTORIALROOT/evaluator/evaluate/server.go provides the following functionality:
  • Creates a gRPC service that listens on the configured port
  • Implements the Evaluate() interface that Open Match prescribes
  • Accepts a stream of proposals in its implementation for this interface and then calls into a simplified helper method.
  • Streams back results from the helper method to Open Match.
Below is the helper method in where the core evaluation logic should be implemented. At runtime, Open Match calls the method and streams the proposals for evaluation. This triggers the method with a list of proposals. The method should de-collide the proposals and return a list of results that Open Match will then return back to the Director.evaluate()$TUTORIALROOT/evaluator/evaluate/evaluator.goEvaluate()evaluate()evaluate()
Copy
Please add your evaluation logic to this method. Here are some strategies for evaluation you may use when you detect Matches with overlapping Tickets:
  1. Aggregate the wait time of the Tickets on the Match. The Match with higher aggregate wait time is selected and the rest are discarded.
  2. Match with the Ticket with the longest wait time gets selected and others discarded.
These are just suggestions. You can also experiment with your own evaluation criteria for this scenario.
As a reference, you may check the implementation of the tutorial solution Evaluator that uses strategy 2.

 

728x90
๋ฐ˜์‘ํ˜•